yamlint 0.1.0 → 1.0.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 (136) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +31 -9
  3. data/.serena/.gitignore +1 -0
  4. data/.serena/memories/project_overview.md +25 -0
  5. data/.serena/memories/style_and_conventions.md +7 -0
  6. data/.serena/memories/suggested_commands.md +17 -0
  7. data/.serena/memories/task_completion.md +5 -0
  8. data/.serena/project.yml +89 -0
  9. data/CHANGELOG.md +6 -2
  10. data/Gemfile +9 -7
  11. data/LICENSE.txt +1 -1
  12. data/README.md +155 -17
  13. data/Rakefile +10 -3
  14. data/docs/Yamlint/Cli.html +403 -0
  15. data/docs/Yamlint/Config.html +1034 -0
  16. data/docs/Yamlint/Formatter.html +433 -0
  17. data/docs/Yamlint/Linter.html +423 -0
  18. data/docs/Yamlint/Models/LintContext.html +993 -0
  19. data/docs/Yamlint/Models/Problem.html +951 -0
  20. data/docs/Yamlint/Models/Token.html +713 -0
  21. data/docs/Yamlint/Models.html +117 -0
  22. data/docs/Yamlint/Output/Base.html +290 -0
  23. data/docs/Yamlint/Output/Colored.html +293 -0
  24. data/docs/Yamlint/Output/Github.html +260 -0
  25. data/docs/Yamlint/Output/Parsable.html +258 -0
  26. data/docs/Yamlint/Output/Standard.html +270 -0
  27. data/docs/Yamlint/Output.html +208 -0
  28. data/docs/Yamlint/Parser/Comment.html +795 -0
  29. data/docs/Yamlint/Parser/CommentExtractor.html +287 -0
  30. data/docs/Yamlint/Parser/LineParser.html +423 -0
  31. data/docs/Yamlint/Parser/TokenParser/Handler.html +910 -0
  32. data/docs/Yamlint/Parser/TokenParser.html +291 -0
  33. data/docs/Yamlint/Parser.html +117 -0
  34. data/docs/Yamlint/Presets.html +266 -0
  35. data/docs/Yamlint/Rules/Anchors/AnchorHandler.html +678 -0
  36. data/docs/Yamlint/Rules/Anchors.html +314 -0
  37. data/docs/Yamlint/Rules/Base.html +968 -0
  38. data/docs/Yamlint/Rules/Braces.html +335 -0
  39. data/docs/Yamlint/Rules/Brackets.html +335 -0
  40. data/docs/Yamlint/Rules/Colons.html +313 -0
  41. data/docs/Yamlint/Rules/Commas.html +313 -0
  42. data/docs/Yamlint/Rules/CommentRule.html +298 -0
  43. data/docs/Yamlint/Rules/Comments.html +317 -0
  44. data/docs/Yamlint/Rules/CommentsIndentation.html +328 -0
  45. data/docs/Yamlint/Rules/DocumentEnd.html +332 -0
  46. data/docs/Yamlint/Rules/DocumentStart.html +332 -0
  47. data/docs/Yamlint/Rules/EmptyLines.html +300 -0
  48. data/docs/Yamlint/Rules/EmptyValues.html +273 -0
  49. data/docs/Yamlint/Rules/FloatValues.html +383 -0
  50. data/docs/Yamlint/Rules/Hyphens.html +337 -0
  51. data/docs/Yamlint/Rules/Indentation.html +329 -0
  52. data/docs/Yamlint/Rules/KeyDuplicates/DuplicateKeyHandler.html +716 -0
  53. data/docs/Yamlint/Rules/KeyDuplicates.html +258 -0
  54. data/docs/Yamlint/Rules/KeyOrdering/KeyOrderHandler.html +694 -0
  55. data/docs/Yamlint/Rules/KeyOrdering.html +258 -0
  56. data/docs/Yamlint/Rules/LineLength.html +251 -0
  57. data/docs/Yamlint/Rules/LineRule.html +304 -0
  58. data/docs/Yamlint/Rules/NewLineAtEndOfFile.html +308 -0
  59. data/docs/Yamlint/Rules/NewLines.html +310 -0
  60. data/docs/Yamlint/Rules/OctalValues.html +270 -0
  61. data/docs/Yamlint/Rules/QuotedStrings.html +381 -0
  62. data/docs/Yamlint/Rules/Registry.html +492 -0
  63. data/docs/Yamlint/Rules/TokenRule.html +298 -0
  64. data/docs/Yamlint/Rules/TrailingSpaces.html +321 -0
  65. data/docs/Yamlint/Rules/Truthy.html +288 -0
  66. data/docs/Yamlint/Rules.html +190 -0
  67. data/docs/Yamlint/Runner.html +551 -0
  68. data/docs/Yamlint.html +135 -0
  69. data/docs/_index.html +643 -0
  70. data/docs/class_list.html +54 -0
  71. data/docs/css/common.css +1 -0
  72. data/docs/css/full_list.css +58 -0
  73. data/docs/css/style.css +490 -0
  74. data/docs/file.README.html +276 -0
  75. data/docs/file_list.html +59 -0
  76. data/docs/frames.html +22 -0
  77. data/docs/index.html +276 -0
  78. data/docs/js/app.js +395 -0
  79. data/docs/js/full_list.js +244 -0
  80. data/docs/js/jquery.js +4 -0
  81. data/docs/method_list.html +1582 -0
  82. data/docs/top-level-namespace.html +110 -0
  83. data/exe/yamlint +7 -0
  84. data/lib/yamlint/cli.rb +162 -0
  85. data/lib/yamlint/config.rb +113 -0
  86. data/lib/yamlint/formatter.rb +140 -0
  87. data/lib/yamlint/linter.rb +130 -0
  88. data/lib/yamlint/models/lint_context.rb +43 -0
  89. data/lib/yamlint/models/problem.rb +44 -0
  90. data/lib/yamlint/models/token.rb +22 -0
  91. data/lib/yamlint/models.rb +9 -0
  92. data/lib/yamlint/output/base.rb +15 -0
  93. data/lib/yamlint/output/colored.rb +54 -0
  94. data/lib/yamlint/output/github.rb +20 -0
  95. data/lib/yamlint/output/parsable.rb +19 -0
  96. data/lib/yamlint/output/standard.rb +25 -0
  97. data/lib/yamlint/output.rb +26 -0
  98. data/lib/yamlint/parser/comment_extractor.rb +78 -0
  99. data/lib/yamlint/parser/line_parser.rb +30 -0
  100. data/lib/yamlint/parser/token_parser.rb +92 -0
  101. data/lib/yamlint/parser.rb +10 -0
  102. data/lib/yamlint/presets/default.rb +35 -0
  103. data/lib/yamlint/presets/relaxed.rb +34 -0
  104. data/lib/yamlint/presets.rb +19 -0
  105. data/lib/yamlint/rules/anchors.rb +133 -0
  106. data/lib/yamlint/rules/base.rb +102 -0
  107. data/lib/yamlint/rules/braces.rb +105 -0
  108. data/lib/yamlint/rules/brackets.rb +105 -0
  109. data/lib/yamlint/rules/colons.rb +73 -0
  110. data/lib/yamlint/rules/commas.rb +85 -0
  111. data/lib/yamlint/rules/comments.rb +77 -0
  112. data/lib/yamlint/rules/comments_indentation.rb +66 -0
  113. data/lib/yamlint/rules/document_end.rb +45 -0
  114. data/lib/yamlint/rules/document_start.rb +45 -0
  115. data/lib/yamlint/rules/empty_lines.rb +107 -0
  116. data/lib/yamlint/rules/empty_values.rb +43 -0
  117. data/lib/yamlint/rules/float_values.rb +67 -0
  118. data/lib/yamlint/rules/hyphens.rb +42 -0
  119. data/lib/yamlint/rules/indentation.rb +39 -0
  120. data/lib/yamlint/rules/key_duplicates.rb +127 -0
  121. data/lib/yamlint/rules/key_ordering.rb +126 -0
  122. data/lib/yamlint/rules/line_length.rb +57 -0
  123. data/lib/yamlint/rules/new_line_at_end_of_file.rb +31 -0
  124. data/lib/yamlint/rules/new_lines.rb +59 -0
  125. data/lib/yamlint/rules/octal_values.rb +62 -0
  126. data/lib/yamlint/rules/quoted_strings.rb +73 -0
  127. data/lib/yamlint/rules/registry.rb +48 -0
  128. data/lib/yamlint/rules/trailing_spaces.rb +31 -0
  129. data/lib/yamlint/rules/truthy.rb +48 -0
  130. data/lib/yamlint/rules.rb +41 -0
  131. data/lib/yamlint/runner.rb +80 -0
  132. data/lib/yamlint/version.rb +1 -1
  133. data/lib/yamlint.rb +11 -3
  134. metadata +131 -11
  135. data/CODE_OF_CONDUCT.md +0 -84
  136. data/sig/yamlint.rbs +0 -4
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yamlint
4
+ module Rules
5
+ class Base
6
+ class << self
7
+ attr_reader :id, :description, :default_options
8
+
9
+ def rule_id(id)
10
+ @id = id
11
+ end
12
+
13
+ def desc(description)
14
+ @description = description
15
+ end
16
+
17
+ def defaults(options)
18
+ @default_options = options
19
+ end
20
+
21
+ def inherited(subclass)
22
+ super
23
+ subclass.instance_variable_set(:@default_options, {})
24
+ end
25
+ end
26
+
27
+ attr_reader :config, :level
28
+
29
+ def initialize(config = {})
30
+ @config = (self.class.default_options || {}).merge(config)
31
+ @level = @config[:level] || :error
32
+ end
33
+
34
+ def check(_context)
35
+ raise NotImplementedError, "#{self.class}#check must be implemented"
36
+ end
37
+
38
+ def fixable?
39
+ false
40
+ end
41
+
42
+ protected
43
+
44
+ def problem(line:, column:, message:, fixable: false)
45
+ Models::Problem.new(
46
+ line:,
47
+ column:,
48
+ rule: self.class.id,
49
+ level: @level,
50
+ message:,
51
+ fixable:
52
+ )
53
+ end
54
+ end
55
+
56
+ class LineRule < Base
57
+ def check(context)
58
+ problems = []
59
+ context.lines.each_with_index do |line, index|
60
+ line_number = index + 1
61
+ line_problems = check_line(line, line_number, context)
62
+ problems.concat(Array(line_problems))
63
+ end
64
+ problems
65
+ end
66
+
67
+ def check_line(_line, _line_number, _context)
68
+ raise NotImplementedError, "#{self.class}#check_line must be implemented"
69
+ end
70
+ end
71
+
72
+ class TokenRule < Base
73
+ def check(context)
74
+ problems = []
75
+ context.tokens.each do |token|
76
+ token_problems = check_token(token, context)
77
+ problems.concat(Array(token_problems))
78
+ end
79
+ problems
80
+ end
81
+
82
+ def check_token(_token, _context)
83
+ raise NotImplementedError, "#{self.class}#check_token must be implemented"
84
+ end
85
+ end
86
+
87
+ class CommentRule < Base
88
+ def check(context)
89
+ problems = []
90
+ context.comments.each do |comment|
91
+ comment_problems = check_comment(comment, context)
92
+ problems.concat(Array(comment_problems))
93
+ end
94
+ problems
95
+ end
96
+
97
+ def check_comment(_comment, _context)
98
+ raise NotImplementedError, "#{self.class}#check_comment must be implemented"
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'English'
4
+ module Yamlint
5
+ module Rules
6
+ class Braces < LineRule
7
+ rule_id 'braces'
8
+ desc 'Check spaces inside braces.'
9
+ defaults({
10
+ forbid: false,
11
+ 'min-spaces-inside': 0,
12
+ 'max-spaces-inside': 0,
13
+ 'min-spaces-inside-empty': -1,
14
+ 'max-spaces-inside-empty': -1
15
+ })
16
+
17
+ def check_line(line, line_number, _context)
18
+ return if line.strip.empty?
19
+ return if line.strip.start_with?('#')
20
+
21
+ problems = []
22
+
23
+ if @config[:forbid] && line.include?('{')
24
+ problems << problem(
25
+ line: line_number,
26
+ column: line.index('{') + 1,
27
+ message: 'flow mapping (braces) forbidden',
28
+ fixable: false
29
+ )
30
+ return problems
31
+ end
32
+
33
+ problems.concat(check_opening_brace(line, line_number))
34
+ problems.concat(check_closing_brace(line, line_number))
35
+ problems
36
+ end
37
+
38
+ def fixable?
39
+ true
40
+ end
41
+
42
+ private
43
+
44
+ def check_opening_brace(line, line_number)
45
+ problems = []
46
+ min_spaces = @config[:'min-spaces-inside']
47
+ max_spaces = @config[:'max-spaces-inside']
48
+
49
+ line.scan(/\{(\s*)(?!\})/) do |match|
50
+ spaces = match[0]
51
+ pos = $LAST_MATCH_INFO.begin(0)
52
+
53
+ if spaces.length < min_spaces
54
+ problems << problem(
55
+ line: line_number,
56
+ column: pos + 2,
57
+ message: "too few spaces inside braces (#{spaces.length} < #{min_spaces})",
58
+ fixable: true
59
+ )
60
+ elsif spaces.length > max_spaces
61
+ problems << problem(
62
+ line: line_number,
63
+ column: pos + 2,
64
+ message: "too many spaces inside braces (#{spaces.length} > #{max_spaces})",
65
+ fixable: true
66
+ )
67
+ end
68
+ end
69
+
70
+ problems
71
+ end
72
+
73
+ def check_closing_brace(line, line_number)
74
+ problems = []
75
+ min_spaces = @config[:'min-spaces-inside']
76
+ max_spaces = @config[:'max-spaces-inside']
77
+
78
+ line.scan(/(?<!\{)(\s*)\}/) do |match|
79
+ spaces = match[0]
80
+ pos = $LAST_MATCH_INFO.begin(0)
81
+
82
+ if spaces.length < min_spaces
83
+ problems << problem(
84
+ line: line_number,
85
+ column: pos + 1,
86
+ message: "too few spaces inside braces (#{spaces.length} < #{min_spaces})",
87
+ fixable: true
88
+ )
89
+ elsif spaces.length > max_spaces
90
+ problems << problem(
91
+ line: line_number,
92
+ column: pos + 1,
93
+ message: "too many spaces inside braces (#{spaces.length} > #{max_spaces})",
94
+ fixable: true
95
+ )
96
+ end
97
+ end
98
+
99
+ problems
100
+ end
101
+ end
102
+
103
+ Registry.register(Braces)
104
+ end
105
+ end
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'English'
4
+ module Yamlint
5
+ module Rules
6
+ class Brackets < LineRule
7
+ rule_id 'brackets'
8
+ desc 'Check spaces inside brackets.'
9
+ defaults({
10
+ forbid: false,
11
+ 'min-spaces-inside': 0,
12
+ 'max-spaces-inside': 0,
13
+ 'min-spaces-inside-empty': -1,
14
+ 'max-spaces-inside-empty': -1
15
+ })
16
+
17
+ def check_line(line, line_number, _context)
18
+ return if line.strip.empty?
19
+ return if line.strip.start_with?('#')
20
+
21
+ problems = []
22
+
23
+ if @config[:forbid] && line.include?('[')
24
+ problems << problem(
25
+ line: line_number,
26
+ column: line.index('[') + 1,
27
+ message: 'flow sequence (brackets) forbidden',
28
+ fixable: false
29
+ )
30
+ return problems
31
+ end
32
+
33
+ problems.concat(check_opening_bracket(line, line_number))
34
+ problems.concat(check_closing_bracket(line, line_number))
35
+ problems
36
+ end
37
+
38
+ def fixable?
39
+ true
40
+ end
41
+
42
+ private
43
+
44
+ def check_opening_bracket(line, line_number)
45
+ problems = []
46
+ min_spaces = @config[:'min-spaces-inside']
47
+ max_spaces = @config[:'max-spaces-inside']
48
+
49
+ line.scan(/\[(\s*)(?!\])/) do |match|
50
+ spaces = match[0]
51
+ pos = $LAST_MATCH_INFO.begin(0)
52
+
53
+ if spaces.length < min_spaces
54
+ problems << problem(
55
+ line: line_number,
56
+ column: pos + 2,
57
+ message: "too few spaces inside brackets (#{spaces.length} < #{min_spaces})",
58
+ fixable: true
59
+ )
60
+ elsif spaces.length > max_spaces
61
+ problems << problem(
62
+ line: line_number,
63
+ column: pos + 2,
64
+ message: "too many spaces inside brackets (#{spaces.length} > #{max_spaces})",
65
+ fixable: true
66
+ )
67
+ end
68
+ end
69
+
70
+ problems
71
+ end
72
+
73
+ def check_closing_bracket(line, line_number)
74
+ problems = []
75
+ min_spaces = @config[:'min-spaces-inside']
76
+ max_spaces = @config[:'max-spaces-inside']
77
+
78
+ line.scan(/(?<!\[)(\s*)\]/) do |match|
79
+ spaces = match[0]
80
+ pos = $LAST_MATCH_INFO.begin(0)
81
+
82
+ if spaces.length < min_spaces
83
+ problems << problem(
84
+ line: line_number,
85
+ column: pos + 1,
86
+ message: "too few spaces inside brackets (#{spaces.length} < #{min_spaces})",
87
+ fixable: true
88
+ )
89
+ elsif spaces.length > max_spaces
90
+ problems << problem(
91
+ line: line_number,
92
+ column: pos + 1,
93
+ message: "too many spaces inside brackets (#{spaces.length} > #{max_spaces})",
94
+ fixable: true
95
+ )
96
+ end
97
+ end
98
+
99
+ problems
100
+ end
101
+ end
102
+
103
+ Registry.register(Brackets)
104
+ end
105
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'English'
4
+ module Yamlint
5
+ module Rules
6
+ class Colons < LineRule
7
+ rule_id 'colons'
8
+ desc 'Check spaces before and after colons.'
9
+ defaults({
10
+ 'max-spaces-before': 0,
11
+ 'max-spaces-after': 1
12
+ })
13
+
14
+ def check_line(line, line_number, _context)
15
+ return if line.strip.empty?
16
+ return if line.strip.start_with?('#')
17
+
18
+ problems = []
19
+ problems.concat(check_spaces_before_colon(line, line_number))
20
+ problems.concat(check_spaces_after_colon(line, line_number))
21
+ problems
22
+ end
23
+
24
+ def fixable?
25
+ true
26
+ end
27
+
28
+ private
29
+
30
+ def check_spaces_before_colon(line, line_number)
31
+ problems = []
32
+ max_before = @config[:'max-spaces-before']
33
+
34
+ line.scan(/(\s+):/) do |match|
35
+ spaces = match[0]
36
+ next unless spaces.length > max_before
37
+
38
+ pos = $LAST_MATCH_INFO.begin(0)
39
+ problems << problem(
40
+ line: line_number,
41
+ column: pos + 1,
42
+ message: "too many spaces before colon (#{spaces.length} > #{max_before})",
43
+ fixable: true
44
+ )
45
+ end
46
+
47
+ problems
48
+ end
49
+
50
+ def check_spaces_after_colon(line, line_number)
51
+ problems = []
52
+ max_after = @config[:'max-spaces-after']
53
+
54
+ line.scan(/:(\s{2,})/) do |match|
55
+ spaces = match[0]
56
+ next if spaces.include?("\n")
57
+
58
+ pos = $LAST_MATCH_INFO.begin(0)
59
+ problems << problem(
60
+ line: line_number,
61
+ column: pos + 2,
62
+ message: "too many spaces after colon (#{spaces.length} > #{max_after})",
63
+ fixable: true
64
+ )
65
+ end
66
+
67
+ problems
68
+ end
69
+ end
70
+
71
+ Registry.register(Colons)
72
+ end
73
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'English'
4
+ module Yamlint
5
+ module Rules
6
+ class Commas < LineRule
7
+ rule_id 'commas'
8
+ desc 'Check spaces before and after commas.'
9
+ defaults({
10
+ 'max-spaces-before': 0,
11
+ 'min-spaces-after': 1,
12
+ 'max-spaces-after': 1
13
+ })
14
+
15
+ def check_line(line, line_number, _context)
16
+ return if line.strip.empty?
17
+ return if line.strip.start_with?('#')
18
+
19
+ problems = []
20
+ problems.concat(check_spaces_before_comma(line, line_number))
21
+ problems.concat(check_spaces_after_comma(line, line_number))
22
+ problems
23
+ end
24
+
25
+ def fixable?
26
+ true
27
+ end
28
+
29
+ private
30
+
31
+ def check_spaces_before_comma(line, line_number)
32
+ problems = []
33
+ max_before = @config[:'max-spaces-before']
34
+
35
+ line.scan(/(\s+),/) do |match|
36
+ spaces = match[0]
37
+ next unless spaces.length > max_before
38
+
39
+ pos = $LAST_MATCH_INFO.begin(0)
40
+ problems << problem(
41
+ line: line_number,
42
+ column: pos + 1,
43
+ message: "too many spaces before comma (#{spaces.length} > #{max_before})",
44
+ fixable: true
45
+ )
46
+ end
47
+
48
+ problems
49
+ end
50
+
51
+ def check_spaces_after_comma(line, line_number)
52
+ problems = []
53
+ min_after = @config[:'min-spaces-after']
54
+ max_after = @config[:'max-spaces-after']
55
+
56
+ line.scan(/,(\s*)/) do |match|
57
+ spaces = match[0]
58
+ next if spaces.include?("\n")
59
+
60
+ pos = $LAST_MATCH_INFO.begin(0)
61
+
62
+ if spaces.length < min_after
63
+ problems << problem(
64
+ line: line_number,
65
+ column: pos + 2,
66
+ message: "too few spaces after comma (#{spaces.length} < #{min_after})",
67
+ fixable: true
68
+ )
69
+ elsif spaces.length > max_after
70
+ problems << problem(
71
+ line: line_number,
72
+ column: pos + 2,
73
+ message: "too many spaces after comma (#{spaces.length} > #{max_after})",
74
+ fixable: true
75
+ )
76
+ end
77
+ end
78
+
79
+ problems
80
+ end
81
+ end
82
+
83
+ Registry.register(Commas)
84
+ end
85
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'English'
4
+ module Yamlint
5
+ module Rules
6
+ class Comments < LineRule
7
+ rule_id 'comments'
8
+ desc 'Check comments formatting.'
9
+ defaults({
10
+ 'require-starting-space': true,
11
+ 'ignore-shebangs': true,
12
+ 'min-spaces-from-content': 2
13
+ })
14
+
15
+ def check_line(line, line_number, _context)
16
+ return unless line.include?('#')
17
+
18
+ problems = []
19
+
20
+ return problems if @config[:'ignore-shebangs'] && line_number == 1 && line.start_with?('#!')
21
+
22
+ problems.concat(check_starting_space(line, line_number))
23
+ problems.concat(check_spaces_from_content(line, line_number))
24
+ problems
25
+ end
26
+
27
+ def fixable?
28
+ true
29
+ end
30
+
31
+ private
32
+
33
+ def check_starting_space(line, line_number)
34
+ return [] unless @config[:'require-starting-space']
35
+
36
+ problems = []
37
+
38
+ line.scan(/#([^\s#])/) do |match|
39
+ next if match[0] == '!'
40
+
41
+ pos = $LAST_MATCH_INFO.begin(0)
42
+ problems << problem(
43
+ line: line_number,
44
+ column: pos + 1,
45
+ message: 'missing starting space in comment',
46
+ fixable: true
47
+ )
48
+ end
49
+
50
+ problems
51
+ end
52
+
53
+ def check_spaces_from_content(line, line_number)
54
+ return [] if line.strip.start_with?('#')
55
+
56
+ problems = []
57
+ min_spaces = @config[:'min-spaces-from-content']
58
+
59
+ if (match = line.match(/(\S)(\s*)#/))
60
+ spaces = match[2].length
61
+ if spaces < min_spaces
62
+ problems << problem(
63
+ line: line_number,
64
+ column: match.begin(0) + 2,
65
+ message: "too few spaces before comment (#{spaces} < #{min_spaces})",
66
+ fixable: true
67
+ )
68
+ end
69
+ end
70
+
71
+ problems
72
+ end
73
+ end
74
+
75
+ Registry.register(Comments)
76
+ end
77
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yamlint
4
+ module Rules
5
+ class CommentsIndentation < Base
6
+ rule_id 'comments-indentation'
7
+ desc 'Check comments indentation.'
8
+ defaults({})
9
+
10
+ def check(context)
11
+ problems = []
12
+
13
+ context.lines.each_with_index do |line, index|
14
+ line_number = index + 1
15
+
16
+ next unless line.strip.start_with?('#')
17
+
18
+ current_indent = line[/\A */].length
19
+ expected_indent = expected_indent_for_comment(context.lines, index)
20
+
21
+ next unless expected_indent && current_indent != expected_indent
22
+
23
+ problems << problem(
24
+ line: line_number,
25
+ column: 1,
26
+ message: "comment not indented correctly (expected #{expected_indent}, found #{current_indent})",
27
+ fixable: true
28
+ )
29
+ end
30
+
31
+ problems
32
+ end
33
+
34
+ def fixable?
35
+ true
36
+ end
37
+
38
+ private
39
+
40
+ def expected_indent_for_comment(lines, index)
41
+ next_indent = find_indent(lines, (index + 1)...lines.length)
42
+ return next_indent unless next_indent.nil?
43
+
44
+ previous_indent = find_indent(lines, (index - 1).downto(0))
45
+ return previous_indent unless previous_indent.nil?
46
+
47
+ 0
48
+ end
49
+
50
+ def find_indent(lines, range)
51
+ range.each do |i|
52
+ line = lines[i]
53
+ next if line.nil?
54
+
55
+ stripped = line.strip
56
+ next if stripped.empty? || stripped.start_with?('#')
57
+
58
+ return line[/\A */].length
59
+ end
60
+ nil
61
+ end
62
+ end
63
+
64
+ Registry.register(CommentsIndentation)
65
+ end
66
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yamlint
4
+ module Rules
5
+ class DocumentEnd < Base
6
+ rule_id 'document-end'
7
+ desc 'Require or forbid document end marker.'
8
+ defaults({
9
+ present: false
10
+ })
11
+
12
+ def check(context)
13
+ return [] if context.empty?
14
+
15
+ has_end = context.lines.any? { |line| line.strip == '...' }
16
+ required = @config[:present]
17
+
18
+ if required && !has_end
19
+ [problem(
20
+ line: context.line_count,
21
+ column: 1,
22
+ message: 'missing document end "..."',
23
+ fixable: true
24
+ )]
25
+ elsif !required && has_end
26
+ line_number = context.lines.index { |line| line.strip == '...' } + 1
27
+ [problem(
28
+ line: line_number,
29
+ column: 1,
30
+ message: 'found forbidden document end "..."',
31
+ fixable: true
32
+ )]
33
+ else
34
+ []
35
+ end
36
+ end
37
+
38
+ def fixable?
39
+ true
40
+ end
41
+ end
42
+
43
+ Registry.register(DocumentEnd)
44
+ end
45
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yamlint
4
+ module Rules
5
+ class DocumentStart < Base
6
+ rule_id 'document-start'
7
+ desc 'Require or forbid document start marker.'
8
+ defaults({
9
+ present: true
10
+ })
11
+
12
+ def check(context)
13
+ return [] if context.empty?
14
+
15
+ has_start = context.lines.any? { |line| line.strip == '---' }
16
+ required = @config[:present]
17
+
18
+ if required && !has_start
19
+ [problem(
20
+ line: 1,
21
+ column: 1,
22
+ message: 'missing document start "---"',
23
+ fixable: true
24
+ )]
25
+ elsif !required && has_start
26
+ line_number = context.lines.index { |line| line.strip == '---' } + 1
27
+ [problem(
28
+ line: line_number,
29
+ column: 1,
30
+ message: 'found forbidden document start "---"',
31
+ fixable: true
32
+ )]
33
+ else
34
+ []
35
+ end
36
+ end
37
+
38
+ def fixable?
39
+ true
40
+ end
41
+ end
42
+
43
+ Registry.register(DocumentStart)
44
+ end
45
+ end