yamlfmt 0.1.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 +7 -0
- data/.ruby-version +1 -0
- data/.standard.yml +3 -0
- data/LICENSE +21 -0
- data/README.md +207 -0
- data/Rakefile +10 -0
- data/exe/yamlfmt +5 -0
- data/lib/yamlfmt/cli.rb +227 -0
- data/lib/yamlfmt/config.rb +111 -0
- data/lib/yamlfmt/corrector.rb +67 -0
- data/lib/yamlfmt/document.rb +241 -0
- data/lib/yamlfmt/edit.rb +12 -0
- data/lib/yamlfmt/errors.rb +21 -0
- data/lib/yamlfmt/exclude_matcher.rb +65 -0
- data/lib/yamlfmt/file_finder.rb +75 -0
- data/lib/yamlfmt/finding.rb +16 -0
- data/lib/yamlfmt/processor.rb +39 -0
- data/lib/yamlfmt/rule/ast_based.rb +57 -0
- data/lib/yamlfmt/rule/base.rb +54 -0
- data/lib/yamlfmt/rule/blank_lines.rb +66 -0
- data/lib/yamlfmt/rule/final_newline.rb +46 -0
- data/lib/yamlfmt/rule/line_based.rb +48 -0
- data/lib/yamlfmt/rule/registry.rb +39 -0
- data/lib/yamlfmt/rule/trailing_whitespace.rb +59 -0
- data/lib/yamlfmt/rule/unnecessary_quotes.rb +50 -0
- data/lib/yamlfmt/rule_plan.rb +12 -0
- data/lib/yamlfmt/safety_validator.rb +72 -0
- data/lib/yamlfmt/source_range.rb +38 -0
- data/lib/yamlfmt/unified_diff.rb +127 -0
- data/lib/yamlfmt/version.rb +5 -0
- data/lib/yamlfmt.rb +28 -0
- metadata +112 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yamlfmt
|
|
4
|
+
module Rule
|
|
5
|
+
class LineBased < Base
|
|
6
|
+
Context = Data.define(:line, :index, :lines, :document) do
|
|
7
|
+
def previous_line
|
|
8
|
+
index.positive? ? lines[index - 1] : nil
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def next_line
|
|
12
|
+
lines[index + 1]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def first?
|
|
16
|
+
index.zero?
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def last?
|
|
20
|
+
index == lines.length - 1
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def call(document)
|
|
25
|
+
return [] if document.block_scalar?
|
|
26
|
+
|
|
27
|
+
each_context(document).flat_map do |context|
|
|
28
|
+
Array(check_line(context))
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def check_line(_context)
|
|
33
|
+
raise NotImplementedError
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def each_context(document, &block)
|
|
39
|
+
return enum_for(__method__, document) unless block
|
|
40
|
+
|
|
41
|
+
lines = document.lines
|
|
42
|
+
lines.each_with_index do |line, index|
|
|
43
|
+
yield Context.new(line:, index:, lines:, document:)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yamlfmt
|
|
4
|
+
module Rule
|
|
5
|
+
module Registry
|
|
6
|
+
class << self
|
|
7
|
+
def register(rule_class)
|
|
8
|
+
id = rule_class.rule_id
|
|
9
|
+
raise ArgumentError, "rule must define an id" if id.nil? || id.empty?
|
|
10
|
+
raise ArgumentError, "rule #{id.inspect} is already registered" if rules_by_id.key?(id)
|
|
11
|
+
|
|
12
|
+
rules_by_id[id] = rule_class
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def fetch(id)
|
|
16
|
+
rules_by_id.fetch(id)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def rules
|
|
20
|
+
rules_by_id.values.sort_by { |rule| [rule.priority, rule.rule_id] }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def ids
|
|
24
|
+
rules_by_id.keys.freeze
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def clear
|
|
28
|
+
@rules_by_id = {}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def rules_by_id
|
|
34
|
+
@rules_by_id ||= {}
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yamlfmt
|
|
4
|
+
module Rule
|
|
5
|
+
class TrailingWhitespace < LineBased
|
|
6
|
+
rule_id "trailing-whitespace"
|
|
7
|
+
priority 100
|
|
8
|
+
|
|
9
|
+
def check_line(context)
|
|
10
|
+
line = context.line
|
|
11
|
+
whitespace = line.content[/[ \t]+\z/]
|
|
12
|
+
return unless whitespace
|
|
13
|
+
|
|
14
|
+
ws_start = line.content.bytesize - whitespace.bytesize
|
|
15
|
+
removable_start = removable_trailing_start(line, ws_start, double_quoted_scalar_ranges(context.document))
|
|
16
|
+
return if removable_start >= line.content.bytesize
|
|
17
|
+
|
|
18
|
+
range = SourceRange.new(
|
|
19
|
+
start_offset: line.start_offset + removable_start,
|
|
20
|
+
end_offset: line.start_offset + line.content.bytesize
|
|
21
|
+
)
|
|
22
|
+
correction(range, "trailing whitespace detected", "")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def double_quoted_scalar_ranges(document)
|
|
28
|
+
document.scalar_ranges(style: Psych::Nodes::Scalar::DOUBLE_QUOTED)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def removable_trailing_start(line, ws_start, scalar_ranges)
|
|
32
|
+
removable_start = ws_start
|
|
33
|
+
while removable_start < line.content.bytesize
|
|
34
|
+
byte = line.content.getbyte(removable_start)
|
|
35
|
+
break unless byte == 32 || byte == 9
|
|
36
|
+
|
|
37
|
+
offset = line.start_offset + removable_start
|
|
38
|
+
inside_scalar = scalar_ranges.any? { |range| range.start_offset <= offset && offset < range.end_offset }
|
|
39
|
+
break unless inside_scalar && escaped_whitespace?(line.content, removable_start)
|
|
40
|
+
|
|
41
|
+
removable_start += 1
|
|
42
|
+
end
|
|
43
|
+
removable_start
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def escaped_whitespace?(content, byte_index)
|
|
47
|
+
backslashes = 0
|
|
48
|
+
position = byte_index - 1
|
|
49
|
+
while position >= 0 && content.getbyte(position) == 92
|
|
50
|
+
backslashes += 1
|
|
51
|
+
position -= 1
|
|
52
|
+
end
|
|
53
|
+
backslashes.odd?
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
Registry.register(TrailingWhitespace)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yamlfmt
|
|
4
|
+
module Rule
|
|
5
|
+
class UnnecessaryQuotes < AstBased
|
|
6
|
+
QUOTED_STYLES = [Psych::Nodes::Scalar::SINGLE_QUOTED, Psych::Nodes::Scalar::DOUBLE_QUOTED].freeze
|
|
7
|
+
FLOW_INDICATORS = /[\[\]{},]/
|
|
8
|
+
|
|
9
|
+
rule_id "unnecessary-quotes"
|
|
10
|
+
priority 400
|
|
11
|
+
|
|
12
|
+
def check_node(context)
|
|
13
|
+
node = context.node
|
|
14
|
+
return unless node.is_a?(Psych::Nodes::Scalar)
|
|
15
|
+
return unless QUOTED_STYLES.include?(node.style)
|
|
16
|
+
return unless can_unquote?(node.value, in_flow: context.flow?)
|
|
17
|
+
|
|
18
|
+
range = context.document.range_for(node)
|
|
19
|
+
return unless range
|
|
20
|
+
return if multiline?(context.document.source, range)
|
|
21
|
+
return if context.flow_mapping_key? && missing_flow_key_separation?(context.document.source, range)
|
|
22
|
+
|
|
23
|
+
correction(range, "unnecessary quotes detected", node.value)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def can_unquote?(value, in_flow:)
|
|
29
|
+
return false unless value.is_a?(String) && Psych.dump(value) == "--- #{value}\n"
|
|
30
|
+
|
|
31
|
+
!in_flow || !value.match?(FLOW_INDICATORS)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def multiline?(source, range)
|
|
35
|
+
source.byteslice(range.start_offset, range.length).match?(/[\r\n]/)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def missing_flow_key_separation?(source, range)
|
|
39
|
+
offset = range.end_offset
|
|
40
|
+
offset += 1 while [9, 32].include?(source.getbyte(offset))
|
|
41
|
+
return false unless source.getbyte(offset) == 58
|
|
42
|
+
|
|
43
|
+
following = source.getbyte(offset + 1)
|
|
44
|
+
following && ![9, 10, 13, 32].include?(following)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
Registry.register(UnnecessaryQuotes)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yamlfmt
|
|
4
|
+
class SafetyValidator
|
|
5
|
+
PERMITTED_CLASSES = [Date, Time, Symbol].freeze
|
|
6
|
+
|
|
7
|
+
def call(original_document, candidate_source)
|
|
8
|
+
candidate = Document.new(candidate_source, path: original_document.path)
|
|
9
|
+
validate_values!(original_document, candidate)
|
|
10
|
+
validate_comments!(original_document, candidate)
|
|
11
|
+
candidate
|
|
12
|
+
rescue ParseError, UnsupportedFileError => error
|
|
13
|
+
raise ValidationError, "formatted source could not be parsed safely: #{error.message}"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def validate_values!(original, candidate)
|
|
19
|
+
original_values = load_values(original)
|
|
20
|
+
candidate_values = load_values(candidate)
|
|
21
|
+
return if equivalent?(original_values, candidate_values)
|
|
22
|
+
|
|
23
|
+
raise ValidationError, "formatting changed the YAML value"
|
|
24
|
+
rescue Psych::Exception => error
|
|
25
|
+
raise ValidationError, "YAML value could not be loaded safely: #{error.message}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def validate_comments!(original, candidate)
|
|
29
|
+
return if original.comment_values == candidate.comment_values
|
|
30
|
+
|
|
31
|
+
raise ValidationError, "formatting changed YAML comments"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def load_values(document)
|
|
35
|
+
Psych.safe_load_stream(
|
|
36
|
+
document.source,
|
|
37
|
+
filename: document.path,
|
|
38
|
+
permitted_classes: PERMITTED_CLASSES,
|
|
39
|
+
aliases: true
|
|
40
|
+
)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def equivalent?(left, right, seen = {})
|
|
44
|
+
return true if left.equal?(right)
|
|
45
|
+
return false unless left.instance_of?(right.class)
|
|
46
|
+
|
|
47
|
+
pair = [left.object_id, right.object_id]
|
|
48
|
+
return true if seen[pair]
|
|
49
|
+
|
|
50
|
+
seen[pair] = true
|
|
51
|
+
|
|
52
|
+
case left
|
|
53
|
+
when Array
|
|
54
|
+
left.length == right.length && left.zip(right).all? { |left_item, right_item| equivalent?(left_item, right_item, seen) }
|
|
55
|
+
when Hash
|
|
56
|
+
equivalent_hash?(left, right, seen)
|
|
57
|
+
when Float
|
|
58
|
+
(left.nan? && right.nan?) || left == right
|
|
59
|
+
else
|
|
60
|
+
left == right
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def equivalent_hash?(left, right, seen)
|
|
65
|
+
return false unless left.length == right.length
|
|
66
|
+
|
|
67
|
+
left.to_a.zip(right.to_a).all? do |(left_key, left_value), (right_key, right_value)|
|
|
68
|
+
equivalent?(left_key, right_key, seen) && equivalent?(left_value, right_value, seen)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yamlfmt
|
|
4
|
+
SourceRange = Data.define(:start_offset, :end_offset) do
|
|
5
|
+
def initialize(start_offset:, end_offset:)
|
|
6
|
+
unless start_offset.is_a?(Integer) && end_offset.is_a?(Integer) &&
|
|
7
|
+
start_offset >= 0 && end_offset >= start_offset
|
|
8
|
+
raise ArgumentError, "source range must be a non-negative half-open byte range"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
super
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def length
|
|
15
|
+
end_offset - start_offset
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def empty?
|
|
19
|
+
length.zero?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def cover?(other)
|
|
23
|
+
start_offset <= other.start_offset && end_offset >= other.end_offset
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def overlaps?(other)
|
|
27
|
+
if empty? && other.empty?
|
|
28
|
+
start_offset == other.start_offset
|
|
29
|
+
elsif empty?
|
|
30
|
+
start_offset > other.start_offset && start_offset < other.end_offset
|
|
31
|
+
elsif other.empty?
|
|
32
|
+
other.start_offset > start_offset && other.start_offset < end_offset
|
|
33
|
+
else
|
|
34
|
+
start_offset < other.end_offset && other.start_offset < end_offset
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yamlfmt
|
|
4
|
+
class UnifiedDiff
|
|
5
|
+
CONTEXT_LINES = 3
|
|
6
|
+
MAX_LCS_CELLS = 1_000_000
|
|
7
|
+
|
|
8
|
+
Record = Data.define(:type, :line)
|
|
9
|
+
|
|
10
|
+
def call(before, after, path:)
|
|
11
|
+
return "" if before == after
|
|
12
|
+
|
|
13
|
+
records = diff_records(split_lines(before), split_lines(after))
|
|
14
|
+
hunks = hunk_ranges(records)
|
|
15
|
+
|
|
16
|
+
output = "--- #{path}\n+++ #{path}\n"
|
|
17
|
+
hunks.each { |range| append_hunk(output, records, range) }
|
|
18
|
+
output
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def split_lines(source)
|
|
24
|
+
source.lines(chomp: false)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def diff_records(before, after)
|
|
28
|
+
return fallback_records(before, after) if before.length * after.length > MAX_LCS_CELLS
|
|
29
|
+
|
|
30
|
+
table = lcs_table(before, after)
|
|
31
|
+
records = []
|
|
32
|
+
before_index = 0
|
|
33
|
+
after_index = 0
|
|
34
|
+
|
|
35
|
+
while before_index < before.length && after_index < after.length
|
|
36
|
+
if before[before_index] == after[after_index]
|
|
37
|
+
records << Record.new(type: :equal, line: before[before_index])
|
|
38
|
+
before_index += 1
|
|
39
|
+
after_index += 1
|
|
40
|
+
elsif table[before_index + 1][after_index] >= table[before_index][after_index + 1]
|
|
41
|
+
records << Record.new(type: :delete, line: before[before_index])
|
|
42
|
+
before_index += 1
|
|
43
|
+
else
|
|
44
|
+
records << Record.new(type: :insert, line: after[after_index])
|
|
45
|
+
after_index += 1
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
before.drop(before_index).each { |line| records << Record.new(type: :delete, line:) }
|
|
50
|
+
after.drop(after_index).each { |line| records << Record.new(type: :insert, line:) }
|
|
51
|
+
records
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def lcs_table(before, after)
|
|
55
|
+
table = Array.new(before.length + 1) { Array.new(after.length + 1, 0) }
|
|
56
|
+
|
|
57
|
+
(before.length - 1).downto(0) do |before_index|
|
|
58
|
+
(after.length - 1).downto(0) do |after_index|
|
|
59
|
+
table[before_index][after_index] = if before[before_index] == after[after_index]
|
|
60
|
+
table[before_index + 1][after_index + 1] + 1
|
|
61
|
+
else
|
|
62
|
+
[table[before_index + 1][after_index], table[before_index][after_index + 1]].max
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
table
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def fallback_records(before, after)
|
|
71
|
+
prefix_length = common_prefix_length(before, after)
|
|
72
|
+
suffix_length = common_suffix_length(before.drop(prefix_length), after.drop(prefix_length))
|
|
73
|
+
|
|
74
|
+
prefix = before.first(prefix_length).map { |line| Record.new(type: :equal, line:) }
|
|
75
|
+
deleted = before[prefix_length, before.length - prefix_length - suffix_length].map { |line| Record.new(type: :delete, line:) }
|
|
76
|
+
inserted = after[prefix_length, after.length - prefix_length - suffix_length].map { |line| Record.new(type: :insert, line:) }
|
|
77
|
+
suffix = before.last(suffix_length).map { |line| Record.new(type: :equal, line:) }
|
|
78
|
+
prefix + deleted + inserted + suffix
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def common_prefix_length(before, after)
|
|
82
|
+
limit = [before.length, after.length].min
|
|
83
|
+
(0...limit).find { |index| before[index] != after[index] } || limit
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def common_suffix_length(before, after)
|
|
87
|
+
limit = [before.length, after.length].min
|
|
88
|
+
(0...limit).find { |index| before[-index - 1] != after[-index - 1] } || limit
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def hunk_ranges(records)
|
|
92
|
+
changes = records.each_index.reject { |index| records[index].type == :equal }
|
|
93
|
+
ranges = changes.map do |index|
|
|
94
|
+
[index - CONTEXT_LINES, 0].max..[index + CONTEXT_LINES, records.length - 1].min
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
ranges.each_with_object([]) do |range, merged|
|
|
98
|
+
if merged.last && range.begin <= merged.last.end + 1
|
|
99
|
+
merged[-1] = merged.last.begin..[merged.last.end, range.end].max
|
|
100
|
+
else
|
|
101
|
+
merged << range
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def append_hunk(output, records, range)
|
|
107
|
+
before_start = 1 + records.first(range.begin).count { |record| record.type != :insert }
|
|
108
|
+
after_start = 1 + records.first(range.begin).count { |record| record.type != :delete }
|
|
109
|
+
hunk = records[range]
|
|
110
|
+
before_count = hunk.count { |record| record.type != :insert }
|
|
111
|
+
after_count = hunk.count { |record| record.type != :delete }
|
|
112
|
+
before_start -= 1 if before_count.zero?
|
|
113
|
+
after_start -= 1 if after_count.zero?
|
|
114
|
+
|
|
115
|
+
output << "@@ -#{before_start},#{before_count} +#{after_start},#{after_count} @@\n"
|
|
116
|
+
hunk.each { |record| append_record(output, record) }
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def append_record(output, record)
|
|
120
|
+
prefix = {equal: " ", delete: "-", insert: "+"}.fetch(record.type)
|
|
121
|
+
terminated = record.line.end_with?("\n", "\r")
|
|
122
|
+
content = record.line.delete_suffix("\n")
|
|
123
|
+
output << prefix << content << "\n"
|
|
124
|
+
output << "\\n" unless terminated
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
data/lib/yamlfmt.rb
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "yamlfmt/version"
|
|
4
|
+
require_relative "yamlfmt/errors"
|
|
5
|
+
require_relative "yamlfmt/source_range"
|
|
6
|
+
require_relative "yamlfmt/edit"
|
|
7
|
+
require_relative "yamlfmt/finding"
|
|
8
|
+
require_relative "yamlfmt/config"
|
|
9
|
+
require_relative "yamlfmt/exclude_matcher"
|
|
10
|
+
require_relative "yamlfmt/file_finder"
|
|
11
|
+
require_relative "yamlfmt/document"
|
|
12
|
+
require_relative "yamlfmt/corrector"
|
|
13
|
+
require_relative "yamlfmt/safety_validator"
|
|
14
|
+
require_relative "yamlfmt/processor"
|
|
15
|
+
require_relative "yamlfmt/unified_diff"
|
|
16
|
+
require_relative "yamlfmt/rule/base"
|
|
17
|
+
require_relative "yamlfmt/rule/registry"
|
|
18
|
+
require_relative "yamlfmt/rule/line_based"
|
|
19
|
+
require_relative "yamlfmt/rule/ast_based"
|
|
20
|
+
require_relative "yamlfmt/rule/trailing_whitespace"
|
|
21
|
+
require_relative "yamlfmt/rule/blank_lines"
|
|
22
|
+
require_relative "yamlfmt/rule/final_newline"
|
|
23
|
+
require_relative "yamlfmt/rule/unnecessary_quotes"
|
|
24
|
+
require_relative "yamlfmt/rule_plan"
|
|
25
|
+
require_relative "yamlfmt/cli"
|
|
26
|
+
|
|
27
|
+
module Yamlfmt
|
|
28
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: yamlfmt
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- zeronosu77108
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-09-06 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: psych
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 5.2.5
|
|
20
|
+
- - "<"
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: '6'
|
|
23
|
+
type: :runtime
|
|
24
|
+
prerelease: false
|
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
26
|
+
requirements:
|
|
27
|
+
- - ">="
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: 5.2.5
|
|
30
|
+
- - "<"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '6'
|
|
33
|
+
- !ruby/object:Gem::Dependency
|
|
34
|
+
name: psych-pure
|
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 0.3.0
|
|
40
|
+
type: :runtime
|
|
41
|
+
prerelease: false
|
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: 0.3.0
|
|
47
|
+
description: Applies targeted edits while preserving comments and untouched formatting.
|
|
48
|
+
email:
|
|
49
|
+
- mail@zeronosu77108.com
|
|
50
|
+
executables:
|
|
51
|
+
- yamlfmt
|
|
52
|
+
extensions: []
|
|
53
|
+
extra_rdoc_files: []
|
|
54
|
+
files:
|
|
55
|
+
- ".ruby-version"
|
|
56
|
+
- ".standard.yml"
|
|
57
|
+
- LICENSE
|
|
58
|
+
- README.md
|
|
59
|
+
- Rakefile
|
|
60
|
+
- exe/yamlfmt
|
|
61
|
+
- lib/yamlfmt.rb
|
|
62
|
+
- lib/yamlfmt/cli.rb
|
|
63
|
+
- lib/yamlfmt/config.rb
|
|
64
|
+
- lib/yamlfmt/corrector.rb
|
|
65
|
+
- lib/yamlfmt/document.rb
|
|
66
|
+
- lib/yamlfmt/edit.rb
|
|
67
|
+
- lib/yamlfmt/errors.rb
|
|
68
|
+
- lib/yamlfmt/exclude_matcher.rb
|
|
69
|
+
- lib/yamlfmt/file_finder.rb
|
|
70
|
+
- lib/yamlfmt/finding.rb
|
|
71
|
+
- lib/yamlfmt/processor.rb
|
|
72
|
+
- lib/yamlfmt/rule/ast_based.rb
|
|
73
|
+
- lib/yamlfmt/rule/base.rb
|
|
74
|
+
- lib/yamlfmt/rule/blank_lines.rb
|
|
75
|
+
- lib/yamlfmt/rule/final_newline.rb
|
|
76
|
+
- lib/yamlfmt/rule/line_based.rb
|
|
77
|
+
- lib/yamlfmt/rule/registry.rb
|
|
78
|
+
- lib/yamlfmt/rule/trailing_whitespace.rb
|
|
79
|
+
- lib/yamlfmt/rule/unnecessary_quotes.rb
|
|
80
|
+
- lib/yamlfmt/rule_plan.rb
|
|
81
|
+
- lib/yamlfmt/safety_validator.rb
|
|
82
|
+
- lib/yamlfmt/source_range.rb
|
|
83
|
+
- lib/yamlfmt/unified_diff.rb
|
|
84
|
+
- lib/yamlfmt/version.rb
|
|
85
|
+
homepage: https://github.com/zeronosu77108/yamlfmt
|
|
86
|
+
licenses:
|
|
87
|
+
- MIT
|
|
88
|
+
metadata:
|
|
89
|
+
allowed_push_host: https://rubygems.org
|
|
90
|
+
homepage_uri: https://github.com/zeronosu77108/yamlfmt
|
|
91
|
+
source_code_uri: https://github.com/zeronosu77108/yamlfmt
|
|
92
|
+
rubygems_mfa_required: 'true'
|
|
93
|
+
post_install_message:
|
|
94
|
+
rdoc_options: []
|
|
95
|
+
require_paths:
|
|
96
|
+
- lib
|
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
98
|
+
requirements:
|
|
99
|
+
- - ">="
|
|
100
|
+
- !ruby/object:Gem::Version
|
|
101
|
+
version: '3.3'
|
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
|
+
requirements:
|
|
104
|
+
- - ">="
|
|
105
|
+
- !ruby/object:Gem::Version
|
|
106
|
+
version: '0'
|
|
107
|
+
requirements: []
|
|
108
|
+
rubygems_version: 3.5.16
|
|
109
|
+
signing_key:
|
|
110
|
+
specification_version: 4
|
|
111
|
+
summary: A comment-preserving, minimal-diff YAML formatter for Ruby
|
|
112
|
+
test_files: []
|