yalphabetize 0.2.1 → 0.3.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: 1f090c28c32a6a7248ee2c256ca9d2c166947c113025cf40701471df67de36b0
4
- data.tar.gz: 42c03996392e0d810bbda8e2c2c49df5915d45ddf749d199722edc9d99105cde
3
+ metadata.gz: 702ef0ac265097aa95ae58399f9bd221336ebba2f29ee51b07ff03beb7c471bd
4
+ data.tar.gz: d2da1541ac411f12ba6b3a70534df739cfca69620b07d067dfa75bd18c4d7da7
5
5
  SHA512:
6
- metadata.gz: bd41579935c1d015927274f68bdb525b0b4c9c713fcdc0aa68fa5b23c6c48c26cbf09f7d94d7343969324e78dedc0c2bd3cf8f9a0769a426ec871001f1478fe7
7
- data.tar.gz: ed42eecc90264a3d79ac52e08e15b4f177bda3f1f765bff77a94e965f734c937608bc404f5e9123369ec02335d19cba100d6f109c0661cf79294dfb3e2a2b94e
6
+ metadata.gz: 43205417abde2761326cd34006fa49cbd574d1ec98e5d47a01f9a5769fad51883de9bc7822e206cbabf66c56f91ea54ce3c3d986bae3639550d5e3899a9759ff
7
+ data.tar.gz: 543936dea7ac58dc5857419cd27330214759109fa3bdb8bdf50524964bb4b1f1d6e30ce9a60fce156c70cb5fdc2694b60fc139f80085678d2841d864dd3e070c
data/bin/yalphabetize CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'yalphabetize/cli'
4
+ require_relative '../lib/yalphabetize'
5
5
 
6
6
  exit Yalphabetize::CLI.call(ARGV)
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yalphabetize
4
+ class Aliaser
5
+ def initialize(stream_node)
6
+ @stream_node = stream_node
7
+ @aliases = {}
8
+ end
9
+
10
+ def call
11
+ nodes.each do |node|
12
+ next unless node.respond_to?(:anchor) && node.anchor
13
+
14
+ ensure_anchor_then_alias(node)
15
+ end
16
+ stream_node
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :stream_node, :aliases
22
+
23
+ def ensure_anchor_then_alias(node)
24
+ if node.alias?
25
+ aliases[node.anchor] ||= node
26
+ elsif aliases[node.anchor]
27
+ swap(node, aliases[node.anchor])
28
+ end
29
+ end
30
+
31
+ def swap(anchor_node, alias_node)
32
+ stream_node.each do |node|
33
+ node.children&.map! do |child_node|
34
+ convert_node(child_node, anchor_node, alias_node)
35
+ end
36
+ end
37
+ end
38
+
39
+ def nodes
40
+ stream_node.select do |node|
41
+ node.respond_to?(:anchor) && node.anchor
42
+ end
43
+ end
44
+
45
+ def convert_node(child_node, anchor_node, alias_node)
46
+ if child_node == anchor_node
47
+ alias_node
48
+ elsif child_node == alias_node
49
+ anchor_node
50
+ else
51
+ child_node
52
+ end
53
+ end
54
+ end
55
+ end
@@ -7,6 +7,7 @@ module Yalphabetize
7
7
  end
8
8
 
9
9
  def call
10
+ transform(stream_node)
10
11
  alphabetize(stream_node)
11
12
  stream_node
12
13
  end
@@ -36,5 +37,23 @@ module Yalphabetize
36
37
  node.children.shift
37
38
  end
38
39
  end
40
+
41
+ def transform(node)
42
+ node.children&.each(&method(:transform))
43
+
44
+ return unless node.mapping?
45
+
46
+ pair_up_children(node)
47
+ end
48
+
49
+ def pair_up_children(node)
50
+ children_clone = node.children.dup
51
+
52
+ children_clone.each_slice(2) do |slice|
53
+ node.children.push(slice)
54
+ node.children.shift
55
+ node.children.shift
56
+ end
57
+ end
39
58
  end
40
59
  end
@@ -1,14 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'yalphabetize/alphabetizer'
4
- require 'yalphabetize/file_yalphabetizer'
5
- require 'yalphabetize/logger'
6
- require 'yalphabetize/offence_detector'
7
- require 'yalphabetize/reader'
8
- require 'yalphabetize/writer'
9
- require 'yalphabetize/yaml_finder'
10
- require 'yalphabetizer'
11
-
12
3
  module Yalphabetize
13
4
  class CLI
14
5
  def self.call(argv)
@@ -20,20 +11,15 @@ module Yalphabetize
20
11
  end
21
12
 
22
13
  def call
23
- Yalphabetizer.call(
24
- argv,
25
- reader_class: Yalphabetize::Reader,
26
- finder: Yalphabetize::YamlFinder.new,
27
- alphabetizer_class: Yalphabetize::Alphabetizer,
28
- writer_class: Yalphabetize::Writer,
29
- offence_detector_class: Yalphabetize::OffenceDetector,
30
- logger: Yalphabetize::Logger.new($stdout),
31
- file_yalphabetizer_class: Yalphabetize::FileYalphabetizer
32
- )
14
+ Yalphabetizer.call argv, options
33
15
  end
34
16
 
35
17
  private
36
18
 
37
19
  attr_reader :argv
20
+
21
+ def options
22
+ OptionParser.parse!(argv)
23
+ end
38
24
  end
39
25
  end
@@ -41,7 +41,7 @@ module Yalphabetize
41
41
  end
42
42
 
43
43
  def compile(string)
44
- scanner = Scanner.new(string.b)
44
+ scanner = Scanner.new(string)
45
45
  scanner.scan do |token|
46
46
  next if token.nil?
47
47
  next if token == ''
@@ -29,13 +29,14 @@ module Yalphabetize
29
29
  :logger, :autocorrect, :alphabetizer_class, :writer_class
30
30
 
31
31
  def autocorrect_file
32
- sorted_stream_node = alphabetizer_class.new(unsorted_stream_node).call
33
- writer_class.new(sorted_stream_node, file_path).call
34
- logger.log_correction(file_path)
32
+ alphabetize
33
+ handle_aliases
34
+ rewrite_yml_file
35
+ print_to_log
35
36
  end
36
37
 
37
38
  def offences?
38
- offence_detector_class.new(unsorted_stream_node).offences?
39
+ offence_detector_class.new(stream_node).offences?
39
40
  end
40
41
 
41
42
  def replace_interpolations
@@ -48,12 +49,28 @@ module Yalphabetize
48
49
  end
49
50
  end
50
51
 
52
+ def alphabetize
53
+ alphabetizer_class.new(stream_node).call
54
+ end
55
+
56
+ def handle_aliases
57
+ Aliaser.new(stream_node).call
58
+ end
59
+
60
+ def rewrite_yml_file
61
+ writer_class.new(stream_node, file_path).call
62
+ end
63
+
64
+ def print_to_log
65
+ logger.log_correction(file_path)
66
+ end
67
+
51
68
  def reader
52
69
  @_reader ||= reader_class.new(file_path)
53
70
  end
54
71
 
55
- def unsorted_stream_node
56
- @_unsorted_stream_node ||= reader.to_ast
72
+ def stream_node
73
+ @_stream_node ||= reader.to_ast
57
74
  end
58
75
 
59
76
  def interpolations_mapping
@@ -2,7 +2,9 @@
2
2
 
3
3
  module Yalphabetize
4
4
  class Logger
5
- def initialize(output)
5
+ DEFAULT_OUTPUT = $stdout
6
+
7
+ def initialize(output = DEFAULT_OUTPUT)
6
8
  @output = output
7
9
  @inspected_count = 0
8
10
  @offences = {}
@@ -40,7 +42,7 @@ module Yalphabetize
40
42
 
41
43
  private
42
44
 
43
- attr_reader :output, :offences, :inspected_count
45
+ attr_reader :offences, :inspected_count, :output
44
46
 
45
47
  def puts_offence(file_path, status)
46
48
  case status
@@ -25,7 +25,7 @@ module Yalphabetize
25
25
  end
26
26
 
27
27
  def alphabetized_children?(node)
28
- node.children.each_cons(2).all? { |a, b| (a.first.value <=> b.first.value) <= 0 }
28
+ node.children.each_slice(2).each_cons(2).all? { |a, b| (a.first.value <=> b.first.value) <= 0 }
29
29
  end
30
30
 
31
31
  def each_child_also_alphabetized?(children)
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'optparse'
4
+
5
+ module Yalphabetize
6
+ class OptionParser
7
+ PARSER = ::OptionParser.new do |o|
8
+ o.banner = 'Usage: yalphabetize [options] [file1, file2, ...]'
9
+
10
+ o.on('-a', '--autocorrect', 'Automatically alphabetize inspected yaml files')
11
+ o.on('-h', '--help', 'Prints this help') do
12
+ puts o
13
+ Kernel.exit
14
+ end
15
+ end
16
+
17
+ def self.parse!(argv)
18
+ {}.tap { |options| PARSER.parse!(argv, into: options) }
19
+ end
20
+ end
21
+ end
@@ -2,8 +2,6 @@
2
2
 
3
3
  require 'psych'
4
4
  require 'securerandom'
5
- require 'yalphabetize/erb_compiler'
6
- require 'yalphabetize/parsing_error'
7
5
 
8
6
  module Yalphabetize
9
7
  class Reader
@@ -14,7 +12,6 @@ module Yalphabetize
14
12
 
15
13
  def to_ast
16
14
  substitute_interpolations
17
- transform(stream_node)
18
15
  stream_node
19
16
  end
20
17
 
@@ -51,23 +48,5 @@ module Yalphabetize
51
48
  e.context
52
49
  )
53
50
  end
54
-
55
- def transform(node)
56
- node.children&.each(&method(:transform))
57
-
58
- return unless node.mapping?
59
-
60
- pair_up_children(node)
61
- end
62
-
63
- def pair_up_children(node)
64
- children_clone = node.children.dup
65
-
66
- children_clone.each_slice(2) do |slice|
67
- node.children.push(slice)
68
- node.children.shift
69
- node.children.shift
70
- end
71
- end
72
51
  end
73
52
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Yalphabetize
4
4
  class Version
5
- STRING = '0.2.1'
5
+ STRING = '0.3.0'
6
6
  end
7
7
  end
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yalphabetize
4
+ class Yalphabetizer
5
+ def self.call(args = [], options = {})
6
+ new(args, options).call
7
+ end
8
+
9
+ def initialize(args, options)
10
+ @args = args
11
+ @options = options
12
+ end
13
+
14
+ def call
15
+ initial_log
16
+ process_files
17
+ final_log
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :args, :options
23
+
24
+ def initial_log
25
+ logger.initial_summary(file_paths)
26
+ end
27
+
28
+ def process_files
29
+ file_paths.each(&method(:process_file))
30
+ end
31
+
32
+ def process_file(file_path)
33
+ file_yalphabetizer_class.new(
34
+ file_path,
35
+ reader_class: reader_class,
36
+ offence_detector_class: offence_detector_class,
37
+ logger: logger,
38
+ autocorrect: options[:autocorrect],
39
+ alphabetizer_class: alphabetizer_class,
40
+ writer_class: writer_class
41
+ ).call
42
+ end
43
+
44
+ def file_paths
45
+ @_file_paths ||= finder.paths(only: only_paths, exclude: excluded_paths)
46
+ end
47
+
48
+ def only_paths
49
+ if args.any?
50
+ args
51
+ elsif config
52
+ config['only'] || []
53
+ else
54
+ []
55
+ end
56
+ end
57
+
58
+ def excluded_paths
59
+ if config
60
+ config['exclude'] || []
61
+ else
62
+ []
63
+ end
64
+ end
65
+
66
+ def config
67
+ return unless File.exist?('.yalphabetize.yml')
68
+
69
+ @_config ||= Psych.load_file('.yalphabetize.yml') || {}
70
+ end
71
+
72
+ def final_log
73
+ logger.final_summary
74
+ logger.offences? ? 1 : 0
75
+ end
76
+
77
+ def reader_class
78
+ Yalphabetize::Reader
79
+ end
80
+
81
+ def finder
82
+ Yalphabetize::YamlFinder
83
+ end
84
+
85
+ def alphabetizer_class
86
+ Yalphabetize::Alphabetizer
87
+ end
88
+
89
+ def writer_class
90
+ Yalphabetize::Writer
91
+ end
92
+
93
+ def offence_detector_class
94
+ Yalphabetize::OffenceDetector
95
+ end
96
+
97
+ def logger
98
+ @_logger ||= Yalphabetize::Logger.new
99
+ end
100
+
101
+ def file_yalphabetizer_class
102
+ Yalphabetize::FileYalphabetizer
103
+ end
104
+ end
105
+ end
@@ -6,6 +6,14 @@ module Yalphabetize
6
6
  class YamlFinder
7
7
  YAML_EXTENSIONS = %w[.yml .yaml].freeze
8
8
 
9
+ def self.paths(only:, exclude:)
10
+ if exclude.any?
11
+ new.paths(only) - new.paths(exclude)
12
+ else
13
+ new.paths(only)
14
+ end
15
+ end
16
+
9
17
  def initialize
10
18
  @files = []
11
19
  end
@@ -37,7 +45,7 @@ module Yalphabetize
37
45
  end
38
46
 
39
47
  def files_in_glob(glob)
40
- files_in_dir([glob, glob.gsub('**', '')].uniq)
48
+ files_in_dir([glob, glob.gsub('**/', '').gsub('**', '')].uniq)
41
49
  end
42
50
 
43
51
  def files_in_dir(dir = Dir.pwd)
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'yalphabetize/aliaser'
4
+ require_relative 'yalphabetize/alphabetizer'
5
+ require_relative 'yalphabetize/cli'
6
+ require_relative 'yalphabetize/erb_compiler'
7
+ require_relative 'yalphabetize/file_yalphabetizer'
8
+ require_relative 'yalphabetize/logger'
9
+ require_relative 'yalphabetize/offence_detector'
10
+ require_relative 'yalphabetize/option_parser'
11
+ require_relative 'yalphabetize/parsing_error'
12
+ require_relative 'yalphabetize/reader'
13
+ require_relative 'yalphabetize/version'
14
+ require_relative 'yalphabetize/writer'
15
+ require_relative 'yalphabetize/yalphabetizer'
16
+ require_relative 'yalphabetize/yaml_finder'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yalphabetize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.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-07-11 00:00:00.000000000 Z
11
+ date: 2021-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: psych
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rspec
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +80,20 @@ dependencies:
66
80
  - - ">="
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
69
97
  description:
70
98
  email:
71
99
  executables:
@@ -74,21 +102,25 @@ extensions: []
74
102
  extra_rdoc_files: []
75
103
  files:
76
104
  - bin/yalphabetize
105
+ - lib/yalphabetize.rb
106
+ - lib/yalphabetize/aliaser.rb
77
107
  - lib/yalphabetize/alphabetizer.rb
78
108
  - lib/yalphabetize/cli.rb
79
109
  - lib/yalphabetize/erb_compiler.rb
80
110
  - lib/yalphabetize/file_yalphabetizer.rb
81
111
  - lib/yalphabetize/logger.rb
82
112
  - lib/yalphabetize/offence_detector.rb
113
+ - lib/yalphabetize/option_parser.rb
83
114
  - lib/yalphabetize/parsing_error.rb
84
115
  - lib/yalphabetize/reader.rb
85
116
  - lib/yalphabetize/version.rb
86
117
  - lib/yalphabetize/writer.rb
118
+ - lib/yalphabetize/yalphabetizer.rb
87
119
  - lib/yalphabetize/yaml_finder.rb
88
- - lib/yalphabetizer.rb
89
120
  homepage:
90
121
  licenses: []
91
- metadata: {}
122
+ metadata:
123
+ rubygems_mfa_required: 'true'
92
124
  post_install_message:
93
125
  rdoc_options: []
94
126
  require_paths:
data/lib/yalphabetizer.rb DELETED
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'open3'
4
-
5
- class Yalphabetizer
6
- def self.call(args = [], **options)
7
- new(args, options).call
8
- end
9
-
10
- def initialize(args, options)
11
- @args = args
12
-
13
- @reader_class = options[:reader_class]
14
- @finder = options[:finder]
15
- @alphabetizer_class = options[:alphabetizer_class]
16
- @writer_class = options[:writer_class]
17
- @offence_detector_class = options[:offence_detector_class]
18
- @logger = options[:logger]
19
- @file_yalphabetizer_class = options[:file_yalphabetizer_class]
20
- end
21
-
22
- def call
23
- initial_log
24
- process_files
25
- final_log
26
- end
27
-
28
- private
29
-
30
- attr_reader :args, :reader_class, :finder, :alphabetizer_class, :writer_class,
31
- :offence_detector_class, :logger, :file_yalphabetizer_class
32
-
33
- def initial_log
34
- logger.initial_summary(file_paths)
35
- end
36
-
37
- def process_files
38
- file_paths.each(&method(:process_file))
39
- end
40
-
41
- def process_file(file_path)
42
- file_yalphabetizer_class.new(
43
- file_path,
44
- reader_class: reader_class,
45
- offence_detector_class: offence_detector_class,
46
- logger: logger,
47
- autocorrect: autocorrect?,
48
- alphabetizer_class: alphabetizer_class,
49
- writer_class: writer_class
50
- ).call
51
- end
52
-
53
- def file_paths
54
- explicit_paths = args.reject { |arg| arg[0] == '-' }
55
- finder.paths(explicit_paths)
56
- end
57
-
58
- def autocorrect?
59
- return true if args.include? '-a'
60
- return true if args.include? '--autocorrect'
61
-
62
- false
63
- end
64
-
65
- def final_log
66
- logger.final_summary
67
- logger.offences? ? 1 : 0
68
- end
69
- end