yalphabetize 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e77cd0148a5d6e1d6c31b90a12d9d7cf85fbccea7e5efa6f4240c6f60759e69e
4
- data.tar.gz: d1c1b0c394f0c35a23b41fb05d1ebd39cfcf53f1bbc8c316a7dac4ee3d6fc046
3
+ metadata.gz: b507c005e0407945299b4d297a443fe5f019f876e90bba19e930630c11be8881
4
+ data.tar.gz: 624a56393c2cf67a529ed4542f66a8308c409739c216052d62b4e75997b8b5eb
5
5
  SHA512:
6
- metadata.gz: 3478dcee26fe4f22d25bc81cc6f9bc874c8af9599c76971ae6c51b619c5ee6215600c161d34b36714f27e5a1b579c643f8679a770ce5e2470bf89d17203be085
7
- data.tar.gz: a1bdafe93d32883ebbd8ed601a83f5521ec7519597a02e8f0f6f325c17bb502b291350529c94dfd5b709e6eb83d8ace98a48c12a88a3c2e327e92b5b62341078
6
+ metadata.gz: b77dd2c3d7e92e97e7c7d16cdd9359c6bd5b7084fe7006651a03d3416de73429403f17fcbd0b45f2d09225b842cb4bfb83adb9f48519b3ceb32853339e356e48
7
+ data.tar.gz: 27495a87a0594f9c33751a7f48e67234b1d7e8067b2e095d5dd90d162237fb309243d0c3c0617795638f1f4b837cf478be1d3969b3ff245668bf45645bca5724
data/bin/yalphabetize ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'yalphabetize/reader'
5
+ require 'yalphabetize/alphabetizer'
6
+ require 'yalphabetize/writer'
7
+ require 'yalphabetize/offence_detector'
8
+ require 'yalphabetize/yaml_finder'
9
+ require 'yalphabetize/logger'
10
+ require 'yalphabetizer'
11
+
12
+ reader = Yalphabetize::Reader
13
+ finder = Yalphabetize::YamlFinder.new
14
+ alphabetizer = Yalphabetize::Alphabetizer
15
+ writer = Yalphabetize::Writer
16
+ offence_detector = Yalphabetize::OffenceDetector
17
+ logger = Yalphabetize::Logger.new
18
+
19
+ exit Yalphabetizer.call(
20
+ ARGV,
21
+ reader: reader,
22
+ finder: finder,
23
+ alphabetizer: alphabetizer,
24
+ writer: writer,
25
+ offence_detector: offence_detector,
26
+ logger: logger
27
+ )
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yalphabetize
4
+ class Alphabetizer
5
+ def initialize(stream_node)
6
+ @stream_node = stream_node
7
+ end
8
+
9
+ def call
10
+ alphabetize(stream_node)
11
+ stream_node
12
+ end
13
+
14
+ private
15
+
16
+ attr_reader :stream_node
17
+
18
+ def alphabetize(node)
19
+ if node.mapping?
20
+ alphabetize_children(node)
21
+ unpair_children(node)
22
+ end
23
+
24
+ node.children&.each { |child_node| alphabetize(child_node) }
25
+ end
26
+
27
+ def alphabetize_children(node)
28
+ node.children.sort_by! { |key, _value| key.value }
29
+ end
30
+
31
+ def unpair_children(node)
32
+ children_clone = node.children.dup
33
+
34
+ children_clone.each do |slice|
35
+ node.children.push(*slice)
36
+ node.children.shift
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,76 @@
1
+ module Yalphabetize
2
+ class Logger
3
+ def initialize
4
+ @inspected_count = 0
5
+ @offences = {}
6
+ end
7
+
8
+ def task_summary(file_paths)
9
+ puts "Inspecting #{file_paths.size} YAML files"
10
+ end
11
+
12
+ def log_offence(file_path)
13
+ @inspected_count += 1
14
+ offences[file_path] = :detected
15
+ print red 'O'
16
+ end
17
+
18
+ def log_no_offence
19
+ @inspected_count += 1
20
+ print green '.'
21
+ end
22
+
23
+ def log_inspected_count
24
+ puts "\nInspected: #{inspected_count}"
25
+ end
26
+
27
+ def list_offences
28
+ puts send(list_offences_color, "Offences: #{offences.size}")
29
+
30
+ @offences.each do |file_path, status|
31
+ case status
32
+ when :detected
33
+ puts yellow file_path
34
+ when :corrected
35
+ puts("#{yellow(file_path)} #{green("CORRECTED")}")
36
+ end
37
+ end
38
+ end
39
+
40
+ def offences?
41
+ @offences.any?
42
+ end
43
+
44
+ def log_correction(file_path)
45
+ offences[file_path] = :corrected
46
+ end
47
+
48
+ private
49
+
50
+ attr_reader :offences, :inspected_count
51
+
52
+ def list_offences_color
53
+ if offences?
54
+ :red
55
+ else
56
+ :green
57
+ end
58
+ end
59
+
60
+ def red(string)
61
+ with_color(31, string)
62
+ end
63
+
64
+ def yellow(string)
65
+ with_color(33, string)
66
+ end
67
+
68
+ def green(string)
69
+ with_color(32, string)
70
+ end
71
+
72
+ def with_color(color, string)
73
+ "\e[#{color}m#{string}\e[0m"
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yalphabetize
4
+ class OffenceDetector
5
+ def initialize(stream_node)
6
+ @stream_node = stream_node
7
+ end
8
+
9
+ def offences?
10
+ !alphabetized?(stream_node)
11
+ end
12
+
13
+ private
14
+
15
+ attr_reader :stream_node
16
+
17
+ def alphabetized?(node)
18
+ return false if node.mapping? && !alphabetized_children?(node)
19
+
20
+ if node.children
21
+ each_child_also_alphabetized?(node.children)
22
+ else
23
+ true
24
+ end
25
+ end
26
+
27
+ def alphabetized_children?(node)
28
+ node.children.each_cons(2).all? { |a, b| (a.first.value <=> b.first.value) <= 0 }
29
+ end
30
+
31
+ def each_child_also_alphabetized?(children)
32
+ children.flatten&.inject(true) { |bool, child_node| bool && alphabetized?(child_node) }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'psych'
4
+
5
+ module Yalphabetize
6
+ class Reader
7
+ def initialize(path)
8
+ @path = path
9
+ end
10
+
11
+ def to_ast
12
+ transform(stream_node)
13
+ stream_node
14
+ end
15
+
16
+ private
17
+
18
+ attr_reader :path
19
+
20
+ def stream_node
21
+ @stream_node ||= Psych.parse_stream File.read(path)
22
+ end
23
+
24
+ def transform(node)
25
+ node.children&.each(&method(:transform))
26
+
27
+ return unless node.mapping?
28
+
29
+ pair_up_children(node)
30
+ end
31
+
32
+ def pair_up_children(node)
33
+ children_clone = node.children.dup
34
+
35
+ children_clone.each_slice(2) do |slice|
36
+ node.children.push(slice)
37
+ node.children.shift
38
+ node.children.shift
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yalphabetize
4
+ class Writer
5
+ def initialize(stream_node, path)
6
+ @stream_node = stream_node
7
+ @path = path
8
+ end
9
+
10
+ def call
11
+ File.open(path, 'w') do |file|
12
+ file.write(stream_node.to_yaml)
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ attr_reader :stream_node, :path
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yalphabetize
4
+ class YamlFinder
5
+ def paths
6
+ @_paths ||= begin
7
+ return if `sh -c 'command -v git'`.empty?
8
+
9
+ output, _error, status = Open3.capture3(
10
+ 'git', 'ls-files', '-z', './**/*.yml',
11
+ '--exclude-standard', '--others', '--cached', '--modified'
12
+ )
13
+
14
+ return unless status.success?
15
+
16
+ output.split("\0").uniq.map { |git_file| "#{Dir.pwd}/#{git_file}" }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open3'
4
+ require 'pry'
5
+
6
+ class Yalphabetizer
7
+ def self.call(args = [], **options)
8
+ new(args, options).call
9
+ end
10
+
11
+ def initialize(args, options)
12
+ @args = args
13
+
14
+ @reader = options[:reader]
15
+ @finder = options[:finder]
16
+ @alphabetizer = options[:alphabetizer]
17
+ @writer = options[:writer]
18
+ @offence_detector = options[:offence_detector]
19
+ @logger = options[:logger]
20
+ end
21
+
22
+ def call
23
+ logger.task_summary(file_paths)
24
+
25
+ file_paths.each do |file_path|
26
+ unsorted_stream_node = reader.new(file_path).to_ast
27
+
28
+ if offences?(unsorted_stream_node)
29
+ logger.log_offence(file_path)
30
+ autocorrect(unsorted_stream_node, file_path) if autocorrect?
31
+ else
32
+ logger.log_no_offence
33
+ end
34
+ end
35
+
36
+ logger.log_inspected_count
37
+ logger.list_offences
38
+
39
+ logger.offences? ? 1 : 0
40
+ end
41
+
42
+ private
43
+
44
+ attr_reader :args, :reader, :finder, :alphabetizer, :writer, :offence_detector, :logger
45
+
46
+ def file_paths
47
+ finder.paths
48
+ end
49
+
50
+ def autocorrect?
51
+ return true if args.include? '-a'
52
+ return true if args.include? '-autocorrect'
53
+
54
+ false
55
+ end
56
+
57
+ def autocorrect(unsorted_stream_node, file_path)
58
+ sorted_stream_node = alphabetizer.new(unsorted_stream_node).call
59
+ writer.new(sorted_stream_node, file_path).call
60
+ logger.log_correction(file_path)
61
+ end
62
+
63
+ def offences?(stream_node)
64
+ offence_detector.new(stream_node).offences?
65
+ end
66
+ end
metadata CHANGED
@@ -1,22 +1,30 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yalphabetize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Jenkins
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-21 00:00:00.000000000 Z
11
+ date: 2021-05-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
15
- executables: []
15
+ executables:
16
+ - yalphabetize
16
17
  extensions: []
17
18
  extra_rdoc_files: []
18
19
  files:
19
- - lib/yalphabetize.rb
20
+ - bin/yalphabetize
21
+ - lib/yalphabetize/alphabetizer.rb
22
+ - lib/yalphabetize/logger.rb
23
+ - lib/yalphabetize/offence_detector.rb
24
+ - lib/yalphabetize/reader.rb
25
+ - lib/yalphabetize/writer.rb
26
+ - lib/yalphabetize/yaml_finder.rb
27
+ - lib/yalphabetizer.rb
20
28
  homepage:
21
29
  licenses: []
22
30
  metadata: {}
@@ -35,7 +43,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
35
43
  - !ruby/object:Gem::Version
36
44
  version: '0'
37
45
  requirements: []
38
- rubygems_version: 3.0.3
46
+ rubygems_version: 3.1.4
39
47
  signing_key:
40
48
  specification_version: 4
41
49
  summary: Alphabetize your YAML files
data/lib/yalphabetize.rb DELETED
@@ -1,8 +0,0 @@
1
- class Yalphabetize
2
- def self.call
3
- {
4
- a: :b,
5
- c: :d
6
- }
7
- end
8
- end