danger-toc 0.2.0 → 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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/README.md +101 -15
  4. data/lib/toc/config.rb +57 -32
  5. data/lib/toc/constructors/kramdown_constructor.rb +5 -6
  6. data/lib/toc/constructors.rb +0 -4
  7. data/lib/toc/extractor.rb +2 -1
  8. data/lib/toc/gem_version.rb +1 -1
  9. data/lib/toc/markdown_file.rb +62 -22
  10. data/lib/toc/plugin.rb +53 -33
  11. metadata +43 -61
  12. data/.gitignore +0 -11
  13. data/.rspec +0 -2
  14. data/.rubocop.yml +0 -14
  15. data/.rubocop_todo.yml +0 -81
  16. data/.travis.yml +0 -14
  17. data/CONTRIBUTING.md +0 -125
  18. data/Dangerfile +0 -4
  19. data/Gemfile +0 -16
  20. data/Guardfile +0 -19
  21. data/RELEASING.md +0 -67
  22. data/Rakefile +0 -23
  23. data/danger-toc.gemspec +0 -23
  24. data/images/toc-missing.png +0 -0
  25. data/spec/config_spec.rb +0 -60
  26. data/spec/constructors_spec.rb +0 -23
  27. data/spec/fixtures/markdown_file/one_section.md +0 -5
  28. data/spec/fixtures/markdown_file/one_section_with_custom_toc.md +0 -11
  29. data/spec/fixtures/markdown_file/one_section_with_invalid_toc.md +0 -11
  30. data/spec/fixtures/markdown_file/one_section_with_toc.md +0 -11
  31. data/spec/fixtures/markdown_file/one_section_with_toc_level.md +0 -11
  32. data/spec/fixtures/markdown_file/one_section_with_underscore_in_name.md +0 -11
  33. data/spec/fixtures/markdown_file/with_quoted_example.md +0 -26
  34. data/spec/markdown_file/danger_toc_readme_spec.rb +0 -19
  35. data/spec/markdown_file/one_section_spec.rb +0 -28
  36. data/spec/markdown_file/one_section_with_toc_level_spec.rb +0 -28
  37. data/spec/markdown_file/one_section_with_toc_spec.rb +0 -28
  38. data/spec/markdown_file/with_quoted_example_spec.rb +0 -33
  39. data/spec/markdown_file/with_underscore_in_section_name_spec.rb +0 -32
  40. data/spec/spec_helper.rb +0 -38
  41. data/spec/toc_spec.rb +0 -134
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1d27e70d24b49b9cb6028e5f55a4315740babe9e9f51a73fe95d7c502e2c18b2
4
- data.tar.gz: f58a7d7c22ae8f8746f9aa9318dbf461511149d5f3881bc9e927020723a80359
3
+ metadata.gz: 873eadcebb5c7ad1e01a9789251aaaf974f3852e6259d85cb95c4799c6d151b5
4
+ data.tar.gz: 4a852a1f1e5b173d136c47e022bd8037d7bdb40f0d09158460f8c53a0b39c1f1
5
5
  SHA512:
6
- metadata.gz: cb815bca9f3cf08a3f6b2a474cdd9c15d8eb3b92c7478e595c86c62a510b52e55e1ef542a6121ca06fa4210239d6dfa4dcb50c26366e3e2adaffc639e6ef66e5
7
- data.tar.gz: 36cb65b82c3ba399ef44a45c2f461f7b7cad09d857eadcb86265f7758370314637550ec1777db7a2c8ea8fa0a44e43d5ede2f4169600cd0bb31efe2531f27c16
6
+ metadata.gz: 1f163608c603f0e539a9e26ed82580b0ecfd22b120fc055e9376811645527147d2d0f243535898d123737307b0cdc5e2423c09c9fc533cb07d392c1f7fb12595
7
+ data.tar.gz: 1b5b1e067a7491ba736f62b4cada1226cb814bcbbe14c43774f6733e2a3c8c4d199b88125fdbfda4de1ee07aa6e4460439677411b53e5ce7e159774681534d51
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  ## Changelog
2
2
 
3
+ ### 0.3.0 (2026-10-20)
4
+
5
+ * [#21](https://github.com/dblock/danger-toc/pull/21): Support every global TOC setting as a per-check keyword override without changing defaults; snapshot configuration and report every failing file - [@dblock](https://github.com/dblock).
6
+ * [#20](https://github.com/dblock/danger-toc/pull/20): Configure bullets, indentation, maximum heading depth, and input parsers; exclude document titles from missing TOCs and support opt-in diff reports - [@dblock](https://github.com/dblock).
7
+ * [#19](https://github.com/dblock/danger-toc/pull/19): Require Ruby 3.1, test through Ruby 4.0, declare the GFM parser dependency, and update pinned Danger workflows and contributor and release instructions - [@dblock](https://github.com/dblock).
8
+ * [#18](https://github.com/dblock/danger-toc/pull/18): Migrate to danger-pr-comment workflow - [@dblock](https://github.com/dblock).
9
+ * [#18](https://github.com/dblock/danger-toc/pull/18): Migrate from Travis CI to GitHub Actions - [@dblock](https://github.com/dblock).
10
+ * [#18](https://github.com/dblock/danger-toc/pull/18): Upgrade rubocop to 1.82.0 - [@dblock](https://github.com/dblock).
11
+
3
12
  ### 0.2.0 (2019/07/28)
4
13
 
5
14
  * [#16](https://github.com/dblock/danger-toc/pull/16): Deprecate `check` in favor of `check!` - [@dblock](https://github.com/dblock).
data/README.md CHANGED
@@ -1,17 +1,25 @@
1
1
  # danger-toc
2
2
 
3
- A plugin for [danger.systems](http://danger.systems) that makes sure your project’s `README.md` has a TOC.
3
+ A plugin for [danger.systems](https://danger.systems) that makes sure your project's `README.md` has a TOC. Requires Ruby 3.1 or newer.
4
4
 
5
5
  [![Gem Version](https://badge.fury.io/rb/danger-toc.svg)](https://badge.fury.io/rb/danger-toc)
6
- [![Build Status](https://travis-ci.org/dblock/danger-toc.svg?branch=master)](https://travis-ci.org/dblock/danger-toc)
6
+ [![CI](https://github.com/dblock/danger-toc/actions/workflows/ci.yml/badge.svg)](https://github.com/dblock/danger-toc/actions/workflows/ci.yml)
7
7
 
8
8
  ## Table of Contents
9
9
 
10
10
  - [Installation](#installation)
11
11
  - [Usage](#usage)
12
- - [toc.files](#tocfiles)
13
- - [toc.header](#tocheader)
14
12
  - [toc.check!](#toccheck)
13
+ - [Options](#options)
14
+ - [files](#files)
15
+ - [header](#header)
16
+ - [parser](#parser)
17
+ - [format](#format)
18
+ - [bullet](#bullet)
19
+ - [indent](#indent)
20
+ - [max_depth](#max_depth)
21
+ - [report](#report)
22
+ - [Global Defaults](#global-defaults)
15
23
  - [Contributing](#contributing)
16
24
  - [Copyright](#copyright)
17
25
 
@@ -20,36 +28,114 @@ A plugin for [danger.systems](http://danger.systems) that makes sure your projec
20
28
  Add `danger-toc` to your Gemfile.
21
29
 
22
30
  ```
23
- gem 'danger-toc', '~> 0.1'
31
+ gem 'danger-toc'
24
32
  ```
25
33
 
26
- Add `toc.check` to your Dangerfile. Make a pull request and see this plugin in action.
34
+ Add `toc.check!` to your Dangerfile. Make a pull request and see this plugin in action.
27
35
 
28
36
  <img src='images/toc-missing.png'>
29
37
 
30
38
  ## Usage
31
39
 
32
- Methods and settings from this plugin are available in your `Dangerfile` under the `toc` namespace.
40
+ Methods from this plugin are available in your `Dangerfile` under the `toc` namespace. Every option can be set globally or passed to a check. Per-check options override global defaults without changing them.
33
41
 
34
- ### toc.files
42
+ ### toc.check!
35
43
 
36
- List of files to ensure TOC in, default is `README.md`.
44
+ Check README.md with default options, or pass options for a particular set of files:
37
45
 
38
46
  ```ruby
39
- config.files = [ 'README.md', 'DEV.md' ]
47
+ toc.check!
48
+ toc.check!(files: ['README.md', 'DEV.md'], header: 'Contents')
40
49
  ```
41
50
 
42
- ### toc.header
51
+ The method returns whether all checked TOCs are correct and reports every failing file. Use `toc.toc_changes?(files: ['README.md'])` to detect modified or added files before running a check.
43
52
 
44
- The Table of Contents header, without `#`, default is `Table of Contents`.
53
+ ### Options
45
54
 
46
55
  ```ruby
47
- config.header = 'Custom Table of Contents'
56
+ toc.check!(files: ['README.md'], max_depth: 3)
57
+ toc.check!(files: ['docs/guide.md'], parser: 'Kramdown', format: :kramdown, bullet: '*', indent: 4)
48
58
  ```
49
59
 
50
- ### toc.check!
60
+ #### files
61
+
62
+ File paths to check. Default: `['README.md']`.
63
+
64
+ ```ruby
65
+ toc.check!(files: ['README.md', 'DEV.md'])
66
+ ```
67
+
68
+ #### header
69
+
70
+ TOC heading text, without `#`. Default: `'Table of Contents'`.
71
+
72
+ ```ruby
73
+ toc.check!(header: 'Contents')
74
+ ```
75
+
76
+ When a TOC is missing, a leading `# Title` is excluded if every subsequent heading is nested below it. A lone heading or multiple top-level sections are retained. When a TOC exists, headings before it are excluded.
77
+
78
+ #### parser
79
+
80
+ Kramdown input parser name. Default: `'GFM'`. GFM and Kramdown input are available out of the box; install and require additional Kramdown parsers before selecting them.
81
+
82
+ ```ruby
83
+ toc.check!(parser: 'Kramdown')
84
+ ```
85
+
86
+ #### format
87
+
88
+ Anchor ID format: `:github` (default) or `:kramdown`. This is independent of the input parser.
89
+
90
+ ```ruby
91
+ toc.check!(parser: 'Kramdown', format: :kramdown)
92
+ ```
93
+
94
+ #### bullet
95
+
96
+ List marker: `'-'` (default), `'*'`, or `'+'`.
97
+
98
+ ```ruby
99
+ toc.check!(bullet: '*')
100
+ ```
101
+
102
+ #### indent
103
+
104
+ Non-negative number of spaces per nesting level. Default: `2`.
105
+
106
+ ```ruby
107
+ toc.check!(indent: 4)
108
+ ```
109
+
110
+ #### max_depth
111
+
112
+ Maximum absolute Markdown heading level (1–6). Default: `nil`, including all levels. For example, `2` includes `#` and `##` headings but not `###`.
113
+
114
+ ```ruby
115
+ toc.check!(max_depth: 2)
116
+ ```
117
+
118
+ #### report
119
+
120
+ Report style: `:full` (default) shows the complete expected TOC. Use `:diff` to show mismatched entries with two surrounding entries of context. Removed lines are prefixed with `-`, additions with `+`. Missing TOCs always show the full suggestion.
121
+
122
+ ```ruby
123
+ toc.check!(report: :diff)
124
+ ```
125
+
126
+ ### Global Defaults
127
+
128
+ Set shared defaults on `toc`, then override individual settings for a particular check:
129
+
130
+ ```ruby
131
+ toc.files = ['README.md', 'DEV.md']
132
+ toc.header = 'Contents'
133
+ toc.check!
134
+ toc.check!(files: ['docs/guide.md'], header: 'Guide Contents', parser: 'Kramdown')
135
+ toc.check! # still checks README.md and DEV.md using the Contents header
136
+ ```
51
137
 
52
- Run all checks.
138
+ The same global/per-check choice applies to every option in the table, including `report`, `format`, and `max_depth`. Global settings are shared across plugin instances; each check captures its own immutable configuration snapshot.
53
139
 
54
140
  ## Contributing
55
141
 
data/lib/toc/config.rb CHANGED
@@ -1,56 +1,81 @@
1
1
  module Danger
2
2
  module Toc
3
- module Config
4
- extend self
3
+ class Config
4
+ DEFAULTS = {
5
+ files: ['README.md'].freeze,
6
+ header: 'Table of Contents',
7
+ format: :github,
8
+ parser: 'GFM',
9
+ bullet: '-',
10
+ indent: 2,
11
+ max_depth: nil,
12
+ report: :full
13
+ }.freeze
5
14
 
6
- ATTRIBUTES = %i[
7
- files
8
- header
9
- ].freeze
15
+ ATTRIBUTES = DEFAULTS.keys.freeze
16
+ DELEGATORS = (ATTRIBUTES + ATTRIBUTES.map { |name| :"#{name}=" }).freeze
10
17
 
11
- ACCESSORS = ATTRIBUTES.map { |name| "#{name}=".to_sym }
18
+ VALIDATORS = {
19
+ files: ->(value) { value.is_a?(Array) && value.all? { |file| file.is_a?(String) && !file.strip.empty? } },
20
+ header: ->(value) { value.is_a?(String) && !value.strip.empty? },
21
+ parser: ->(value) { value.is_a?(String) && !value.strip.empty? },
22
+ format: ->(value) { %i[github kramdown].include?(value) },
23
+ bullet: ->(value) { %w[- * +].include?(value) },
24
+ indent: ->(value) { value.is_a?(Integer) && value >= 0 },
25
+ max_depth: ->(value) { value.nil? || (value.is_a?(Integer) && (1..6).cover?(value)) },
26
+ report: ->(value) { %i[full diff].include?(value) }
27
+ }.freeze
12
28
 
13
- DELEGATORS = ATTRIBUTES + ACCESSORS
29
+ attr_reader(*ATTRIBUTES)
14
30
 
15
- attr_accessor(*Config::ATTRIBUTES)
16
- attr_writer :format
17
-
18
- # Files to process
19
- def files=(value)
20
- @files = value
31
+ ATTRIBUTES.each do |name|
32
+ define_method("#{name}=") do |value|
33
+ validate_option!(name, value)
34
+ instance_variable_set("@#{name}", snapshot(value))
35
+ end
21
36
  end
22
37
 
23
- # Table of Contents Header
24
- def header=(value)
25
- @header = value
38
+ def initialize(**options)
39
+ unknown = options.keys - ATTRIBUTES
40
+ raise ArgumentError, "Unknown TOC options: #{unknown.join(', ')}" unless unknown.empty?
41
+
42
+ DEFAULTS.merge(options).each { |name, value| public_send("#{name}=", value) }
26
43
  end
27
44
 
28
- def format
29
- @format ||= default_format
45
+ def with(**options)
46
+ self.class.new(**to_h, **options).freeze
30
47
  end
31
48
 
32
- def default_format
33
- :github
49
+ def to_h
50
+ ATTRIBUTES.to_h { |name| [name, public_send(name)] }
34
51
  end
35
52
 
36
53
  def reset
37
- self.files = ['README.md']
38
- self.header = 'Table of Contents'
39
- self.format = default_format
54
+ DEFAULTS.each { |name, value| public_send("#{name}=", value) }
40
55
  end
41
56
 
42
- reset
43
- end
57
+ private
44
58
 
45
- class << self
46
- def configure
47
- warn '[DEPRECATION] `configure` is deprecated. Please directly configure the Danger plugin via `toc.xyz=` instead.'
48
- block_given? ? yield(Config) : Config
59
+ def validate_option!(name, value)
60
+ raise ArgumentError, "Invalid TOC #{name}: #{value.inspect}" unless VALIDATORS.fetch(name).call(value)
49
61
  end
50
62
 
51
- def config
52
- Config
63
+ def snapshot(value)
64
+ case value
65
+ when Array then value.map { |item| snapshot(item) }.freeze
66
+ when String then value.dup.freeze
67
+ else value
68
+ end
53
69
  end
54
70
  end
71
+
72
+ def self.config
73
+ @config ||= Config.new
74
+ end
75
+
76
+ def self.configure
77
+ warn '[DEPRECATION] `configure` is deprecated. Please directly configure the Danger plugin via `toc.xyz=` instead.'
78
+ block_given? ? yield(config) : config
79
+ end
55
80
  end
56
81
  end
@@ -6,6 +6,7 @@ module Danger
6
6
  class KramdownConstructor < Kramdown::Converter::Toc
7
7
  def flatten(el)
8
8
  return [] unless el.type == :toc
9
+
9
10
  result = []
10
11
  if el.value
11
12
  result << {
@@ -14,20 +15,18 @@ module Danger
14
15
  depth: el.value.options[:level]
15
16
  }
16
17
  end
17
- if el.children
18
- el.children.each do |child|
19
- result.concat(flatten(child))
20
- end
18
+ el.children&.each do |child|
19
+ result.concat(flatten(child))
21
20
  end
22
21
  result
23
22
  end
24
23
 
25
24
  def convert(el)
26
- toc = flatten(super(el))
25
+ toc = flatten(super)
27
26
  has_toc = false
28
27
  headers = []
29
28
  toc.each do |line|
30
- if !has_toc && line[:text] == Danger::Toc.config.header
29
+ if !has_toc && line[:text] == (@options[:toc_header] || 'Table of Contents')
31
30
  headers = [] # drop any headers prior to TOC
32
31
  has_toc = true
33
32
  else
@@ -7,10 +7,6 @@ module Danger
7
7
  def self.get(name)
8
8
  const_get "#{name.to_s.camelize}Constructor"
9
9
  end
10
-
11
- def self.current
12
- get Danger::Toc.config.format
13
- end
14
10
  end
15
11
  end
16
12
  end
data/lib/toc/extractor.rb CHANGED
@@ -8,10 +8,11 @@ module Danger
8
8
  @toc_start = nil
9
9
  @toc_end = nil
10
10
  @in_toc = false
11
+ @toc_header = options.fetch(:toc_header, 'Table of Contents')
11
12
  end
12
13
 
13
14
  def convert(el)
14
- if el.type == :header && el.options[:raw_text] == Danger::Toc.config.header
15
+ if el.type == :header && el.options[:raw_text] == @toc_header
15
16
  @in_toc = true
16
17
  @toc_start = el.options[:location]
17
18
  elsif el.type == :header
@@ -1,3 +1,3 @@
1
1
  module Toc
2
- VERSION = '0.2.0'.freeze
2
+ VERSION = '0.3.0'.freeze
3
3
  end
@@ -1,24 +1,25 @@
1
1
  require 'active_support/core_ext/string/inflections'
2
+ require 'kramdown-parser-gfm'
3
+ require 'diff/lcs'
2
4
 
3
5
  require_relative 'extractor'
4
6
  require_relative 'constructors'
7
+ require_relative 'config'
5
8
 
6
9
  module Danger
7
10
  module Toc
8
11
  class MarkdownFile
9
- attr_reader :filename
10
- attr_reader :exists
11
- attr_reader :toc
12
- attr_reader :headers
12
+ attr_reader :filename, :exists, :toc, :headers, :config
13
13
 
14
- def initialize(filename = 'README.md')
14
+ def initialize(filename = 'README.md', config: Danger::Toc.config.with)
15
+ @config = config
15
16
  @filename = filename
16
17
  @exists = File.exist?(filename)
17
- if @exists
18
- parse!
19
- reduce!
20
- validate!
21
- end
18
+ return unless @exists
19
+
20
+ parse!
21
+ reduce!
22
+ validate!
22
23
  end
23
24
 
24
25
  def exists?
@@ -40,27 +41,66 @@ module Danger
40
41
  def toc_from_headers
41
42
  headers.map do |header|
42
43
  [
43
- ' ' * header[:depth] * 2,
44
- "- [#{header[:text]}]",
44
+ ' ' * header[:depth] * config.indent,
45
+ "#{config.bullet} [#{header[:text]}]",
45
46
  "(##{header[:id]})"
46
47
  ].compact.join
47
48
  end
48
49
  end
49
50
 
51
+ def toc_diff
52
+ changes = Diff::LCS.sdiff(toc || [], toc_from_headers)
53
+ lines = []
54
+ previous = nil
55
+ diff_context(changes).each do |index|
56
+ lines << '...' if previous && index > previous + 1
57
+ lines.concat(diff_lines(changes[index]))
58
+ previous = index
59
+ end
60
+ lines.join("\n")
61
+ end
62
+
50
63
  private
51
64
 
65
+ def diff_context(changes)
66
+ changes.each_index.reject { |index| changes[index].action == '=' }.flat_map do |index|
67
+ (([index - 2, 0].max)..([index + 2, changes.length - 1].min)).to_a
68
+ end.uniq.sort
69
+ end
70
+
71
+ def diff_lines(change)
72
+ case change.action
73
+ when '!' then ["-#{change.old_element}", "+#{change.new_element}"]
74
+ when '-' then ["-#{change.old_element}"]
75
+ when '+' then ["+#{change.new_element}"]
76
+ else [" #{change.old_element}"]
77
+ end
78
+ end
79
+
52
80
  # Parse markdown file for TOC.
53
81
  def parse!
54
82
  md = File.read(filename)
55
- doc = Kramdown::Document.new(md, input: 'GFM')
83
+ doc = Kramdown::Document.new(md, input: config.parser)
84
+
85
+ extract_toc!(md, doc)
86
+ construct_headers!(doc)
87
+ end
56
88
 
57
- # extract toc
58
- toc_start, toc_end = Danger::Toc::Extractor.convert(doc.root).first
89
+ def extract_toc!(markdown, doc)
90
+ toc_start, toc_end = Danger::Toc::Extractor.convert(doc.root, toc_header: config.header).first
91
+ toc_end ||= markdown.lines.length + 1 if toc_start
59
92
  @has_toc = toc_start && toc_end
60
- @toc = md.split("\n")[toc_start, toc_end - toc_start - 1].reject(&:empty?) if @has_toc
93
+ @toc = markdown.split("\n")[toc_start, toc_end - toc_start - 1].reject(&:empty?) if @has_toc
94
+ end
61
95
 
62
- # construct toc
63
- @headers = Danger::Toc::Constructors.current.convert(doc.root).first
96
+ def construct_headers!(doc)
97
+ @headers = Danger::Toc::Constructors.get(config.format).convert(doc.root, toc_header: config.header).first
98
+ headers.shift if !@has_toc && document_title?
99
+ headers.select! { |header| header[:depth] <= config.max_depth } if config.max_depth
100
+ end
101
+
102
+ def document_title?
103
+ headers.length > 1 && headers.first[:depth] == 1 && headers.drop(1).all? { |header| header[:depth] > 1 }
64
104
  end
65
105
 
66
106
  def reduce!
@@ -68,10 +108,10 @@ module Danger
68
108
  headers.each do |header|
69
109
  min_depth = header[:depth] unless min_depth && min_depth < header[:depth]
70
110
  end
71
- if min_depth
72
- headers.each do |header|
73
- header[:depth] -= min_depth
74
- end
111
+ return unless min_depth
112
+
113
+ headers.each do |header|
114
+ header[:depth] -= min_depth
75
115
  end
76
116
  end
77
117
 
data/lib/toc/plugin.rb CHANGED
@@ -7,8 +7,7 @@ module Danger
7
7
  #
8
8
  # @example Customize files and remind the requester to update TOCs when necessary.
9
9
  #
10
- # toc.files = ['README.md']
11
- # toc.is_toc_correct?
10
+ # toc.check!(files: ['README.md'], max_depth: 3)
12
11
  #
13
12
  # @see dblock/danger-toc
14
13
  # @tags toc
@@ -16,54 +15,75 @@ module Danger
16
15
  class DangerToc < Plugin
17
16
  extend Forwardable
18
17
 
19
- def_delegators Danger::Toc.config, *Danger::Toc::Config::DELEGATORS
18
+ def_delegators 'Danger::Toc.config', *Danger::Toc::Config::DELEGATORS
20
19
 
21
20
  # Run all checks.
22
- # @return [void]
23
- def check!
24
- is_toc_correct?
21
+ # @param options [Hash] Per-check files, header, parser, format, bullet, indent, max_depth, and report settings.
22
+ # @return [boolean] Whether all files have correct TOCs.
23
+ def check!(**options)
24
+ config = Danger::Toc.config.with(**options)
25
+ config.files.map { |filename| check_file(filename, config) }.all?
25
26
  end
26
27
 
27
28
  # Run all checks.
28
- # @return [void]
29
- def check
29
+ # @return [boolean]
30
+ def check(**options)
30
31
  warn '[DEPRECATION] `check` is deprecated. Please use `check!` instead.'
31
- check!
32
+ check!(**options)
32
33
  end
33
34
 
34
35
  # Has the README file been modified?
35
36
  # @return [boolean]
36
- def toc_changes?
37
- (git.modified_files & files).any? || (git.added_files & files).any?
37
+ def toc_changes?(**options)
38
+ files = Danger::Toc.config.with(**options).files
39
+ git.modified_files.intersect?(files) || git.added_files.intersect?(files)
38
40
  end
39
41
 
40
42
  # Is the TOC format correct?
41
43
  # @return [boolean]
42
- def is_toc_correct?
43
- files.all? do |filename|
44
- toc_file = Danger::Toc::MarkdownFile.new(filename)
45
- if !toc_file.exists?
46
- messaging.fail("The #{filename} file does not exist.", sticky: false)
47
- false
48
- elsif toc_file.good?
49
- true
50
- else
51
- markdown <<-MARKDOWN
52
- Here's the expected TOC for #{filename}:
44
+ def is_toc_correct?(**options)
45
+ check!(**options)
46
+ end
53
47
 
54
- ```markdown
55
- # #{Danger::Toc.config.header}
48
+ private
56
49
 
57
- #{toc_file.toc_from_headers.join("\n")}
58
- ```
59
- MARKDOWN
60
- if toc_file.has_toc?
61
- messaging.fail("The TOC found in #{filename} doesn't match the sections of the file.", sticky: false)
62
- else
63
- messaging.fail("The #{filename} file is missing a TOC.", sticky: false)
64
- end
65
- false
50
+ def check_file(filename, config)
51
+ toc_file = Danger::Toc::MarkdownFile.new(filename, config: config)
52
+ if !toc_file.exists?
53
+ messaging.fail("The #{filename} file does not exist.", sticky: false)
54
+ false
55
+ elsif toc_file.good?
56
+ true
57
+ else
58
+ report_toc(toc_file)
59
+ if toc_file.has_toc?
60
+ messaging.fail("The TOC found in #{filename} doesn't match the sections of the file.", sticky: false)
61
+ else
62
+ messaging.fail("The #{filename} file is missing a TOC.", sticky: false)
66
63
  end
64
+ false
65
+ end
66
+ end
67
+
68
+ def report_toc(toc_file)
69
+ if toc_file.config.report == :diff && toc_file.has_toc?
70
+ markdown <<~MARKDOWN
71
+ Here's the TOC diff for #{toc_file.filename} (- current, + expected):
72
+
73
+ ```diff
74
+ #{toc_file.toc_diff}
75
+ ```
76
+ MARKDOWN
77
+ else
78
+ markdown <<~MARKDOWN
79
+ Here's the expected TOC for #{toc_file.filename}:
80
+
81
+ ```markdown
82
+ # #{toc_file.config.header}
83
+
84
+ #{toc_file.toc_from_headers.join("\n")}
85
+ ```
86
+ MARKDOWN
67
87
  end
68
88
  end
69
89
  end