tailor 1.0.0.alpha2 → 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 (84) hide show
  1. data/.gitignore +1 -0
  2. data/.tailor +10 -2
  3. data/Gemfile.lock +2 -2
  4. data/History.rdoc +20 -0
  5. data/README.rdoc +176 -26
  6. data/features/configurable.feature +19 -39
  7. data/features/horizontal_spacing.feature +3 -2
  8. data/features/indentation.feature +2 -2
  9. data/features/indentation/bad_files_with_no_trailing_newline.feature +9 -8
  10. data/features/indentation/good_files_with_no_trailing_newline.feature +19 -6
  11. data/features/name_detection.feature +2 -2
  12. data/features/support/env.rb +0 -2
  13. data/features/support/file_cases/horizontal_spacing_cases.rb +5 -4
  14. data/features/support/file_cases/indentation_cases.rb +105 -54
  15. data/features/support/file_cases/naming_cases.rb +0 -1
  16. data/features/support/file_cases/vertical_spacing_cases.rb +0 -1
  17. data/features/support/legacy/bad_ternary_colon_spacing.rb +1 -1
  18. data/features/valid_ruby.feature +17 -0
  19. data/features/vertical_spacing.feature +40 -19
  20. data/lib/ext/string_ext.rb +12 -0
  21. data/lib/tailor/cli.rb +7 -5
  22. data/lib/tailor/cli/options.rb +13 -3
  23. data/lib/tailor/composite_observable.rb +17 -2
  24. data/lib/tailor/configuration.rb +83 -72
  25. data/lib/tailor/configuration/style.rb +85 -0
  26. data/lib/tailor/critic.rb +67 -117
  27. data/lib/tailor/formatter.rb +38 -0
  28. data/lib/tailor/formatters/text.rb +35 -10
  29. data/lib/tailor/lexed_line.rb +38 -5
  30. data/lib/tailor/lexer.rb +150 -14
  31. data/lib/tailor/{lexer_constants.rb → lexer/lexer_constants.rb} +9 -7
  32. data/lib/tailor/lexer/token.rb +6 -2
  33. data/lib/tailor/logger.rb +4 -0
  34. data/lib/tailor/problem.rb +8 -73
  35. data/lib/tailor/reporter.rb +1 -1
  36. data/lib/tailor/ruler.rb +67 -6
  37. data/lib/tailor/rulers/allow_camel_case_methods_ruler.rb +9 -1
  38. data/lib/tailor/rulers/allow_hard_tabs_ruler.rb +9 -1
  39. data/lib/tailor/rulers/allow_invalid_ruby_ruler.rb +38 -0
  40. data/lib/tailor/rulers/allow_screaming_snake_case_classes_ruler.rb +9 -2
  41. data/lib/tailor/rulers/allow_trailing_line_spaces_ruler.rb +10 -5
  42. data/lib/tailor/rulers/indentation_spaces_ruler.rb +93 -26
  43. data/lib/tailor/rulers/indentation_spaces_ruler/indentation_manager.rb +128 -84
  44. data/lib/tailor/rulers/max_code_lines_in_class_ruler.rb +9 -5
  45. data/lib/tailor/rulers/max_code_lines_in_method_ruler.rb +9 -5
  46. data/lib/tailor/rulers/max_line_length_ruler.rb +10 -5
  47. data/lib/tailor/rulers/spaces_after_comma_ruler.rb +13 -4
  48. data/lib/tailor/rulers/spaces_after_lbrace_ruler.rb +8 -4
  49. data/lib/tailor/rulers/spaces_after_lbracket_ruler.rb +8 -4
  50. data/lib/tailor/rulers/spaces_after_lparen_ruler.rb +8 -4
  51. data/lib/tailor/rulers/spaces_before_comma_ruler.rb +8 -4
  52. data/lib/tailor/rulers/spaces_before_lbrace_ruler.rb +13 -6
  53. data/lib/tailor/rulers/spaces_before_rbrace_ruler.rb +12 -8
  54. data/lib/tailor/rulers/spaces_before_rbracket_ruler.rb +12 -5
  55. data/lib/tailor/rulers/spaces_before_rparen_ruler.rb +13 -6
  56. data/lib/tailor/rulers/spaces_in_empty_braces_ruler.rb +13 -9
  57. data/lib/tailor/rulers/trailing_newlines_ruler.rb +10 -5
  58. data/lib/tailor/tailorrc.erb +3 -3
  59. data/lib/tailor/version.rb +1 -1
  60. data/m.rb +15 -0
  61. data/spec/spec_helper.rb +0 -1
  62. data/spec/tailor/cli_spec.rb +8 -9
  63. data/spec/tailor/composite_observable_spec.rb +41 -0
  64. data/spec/tailor/configuration/style_spec.rb +197 -0
  65. data/spec/tailor/configuration_spec.rb +52 -33
  66. data/spec/tailor/critic_spec.rb +7 -8
  67. data/spec/tailor/formatter_spec.rb +52 -0
  68. data/spec/tailor/lexed_line_spec.rb +236 -88
  69. data/spec/tailor/lexer_spec.rb +8 -63
  70. data/spec/tailor/problem_spec.rb +14 -46
  71. data/spec/tailor/reporter_spec.rb +8 -8
  72. data/spec/tailor/ruler_spec.rb +1 -1
  73. data/spec/tailor/rulers/indentation_spaces_ruler/indentation_manager_spec.rb +132 -176
  74. data/spec/tailor/rulers/indentation_spaces_ruler_spec.rb +41 -33
  75. data/spec/tailor/rulers/{spaces_after_comma_spec.rb → spaces_after_comma_ruler_spec.rb} +5 -5
  76. data/spec/tailor/rulers/spaces_after_lbrace_ruler_spec.rb +14 -14
  77. data/spec/tailor/rulers/spaces_before_lbrace_ruler_spec.rb +1 -1
  78. data/spec/tailor/rulers/spaces_before_rbrace_ruler_spec.rb +1 -1
  79. data/spec/tailor/version_spec.rb +1 -1
  80. data/spec/tailor_spec.rb +3 -1
  81. data/tailor.gemspec +11 -3
  82. data/uest.rb +9 -0
  83. metadata +66 -41
  84. data/features/step_definitions/spacing/commas_steps.rb +0 -14
@@ -49,4 +49,3 @@ end}
49
49
  NAMING_1[:two_screaming_snake_module_class] =
50
50
  %Q{module Thing_One_Again
51
51
  end}
52
-
@@ -67,4 +67,3 @@ V_SPACING_1[:parent_method_too_long] =
67
67
  def inner_thing; print '1'; end
68
68
  puts
69
69
  end}
70
-
@@ -28,4 +28,4 @@ $:.unshift File.dirname(__FILE__)
28
28
 
29
29
  # Skip when question mark method is followed by a symbol
30
30
  if bobo[:thing].eql? :clown
31
- end
31
+ end
@@ -0,0 +1,17 @@
1
+ Feature: Valid Ruby
2
+ As a Ruby developer, I want to check my project files to make sure they're
3
+ valid Ruby, so when I see other tailor problems, I know why those problems
4
+ might be there.
5
+
6
+ Scenario: Extra 'end'
7
+ Given a file named "extra_end.rb" with:
8
+ """
9
+ def a_method
10
+ puts "stuff"
11
+ end
12
+ end
13
+
14
+ """
15
+ When I run `tailor -d extra_end.rb`
16
+ Then the output should match /Total Problems.*1/
17
+ And the output should match /File contains invalid Ruby/
@@ -2,18 +2,6 @@ Feature: Vertical spacing
2
2
  As a Ruby developer
3
3
  I want to check my Ruby files for vertical spacing
4
4
 
5
- Background:
6
- Given my configuration file ".tailor" looks like:
7
- """
8
- Tailor.config do |config|
9
- config.file_set do
10
- max_code_lines_in_class 5
11
- max_code_lines_in_method 3
12
- trailing_newlines 0
13
- end
14
- end
15
- """
16
-
17
5
  @bad_files
18
6
  Scenario: Detect lack of newlines
19
7
  Given a file named "not_enough_newlines.rb" with:
@@ -52,11 +40,20 @@ Feature: Vertical spacing
52
40
  When I run `tailor -d .`
53
41
  Then the output should match /Total Problems.*0/
54
42
 
55
- @good_files @class_length
43
+ @multi_line @good_files
56
44
 
57
- @multi_line
45
+ @class_length
58
46
  Scenario Outline: Classes/modules with <= configured lines
59
- Given <File> exists without a newline at the end
47
+ Given my configuration file ".tailor" looks like:
48
+ """
49
+ Tailor.config do |config|
50
+ config.file_set do |style|
51
+ style.max_code_lines_in_class 5
52
+ style.trailing_newlines 0
53
+ end
54
+ end
55
+ """
56
+ And <File> exists without a newline at the end
60
57
  When I run `tailor -d -c .tailor <File>`
61
58
  Then the output should match /Total Problems.*0/
62
59
  And the exit status should be 0
@@ -70,7 +67,15 @@ Feature: Vertical spacing
70
67
 
71
68
  @multi_line
72
69
  Scenario Outline: Lines with bad spacing around parens
73
- Given <File> exists without a newline at the end
70
+ Given my configuration file ".tailor" looks like:
71
+ """
72
+ Tailor.config do |config|
73
+ config.file_set do |style|
74
+ style.max_code_lines_in_class 5
75
+ end
76
+ end
77
+ """
78
+ And <File> exists without a newline at the end
74
79
  When I run `tailor -d -c .tailor <File>`
75
80
  Then the output should match /Total Problems.*<Problems>/
76
81
  And the output should match /position: <Position>/
@@ -86,7 +91,16 @@ Feature: Vertical spacing
86
91
 
87
92
  @multi_line
88
93
  Scenario Outline: Methods with <= configured lines
89
- Given <File> exists without a newline at the end
94
+ Given my configuration file ".tailor" looks like:
95
+ """
96
+ Tailor.config do |config|
97
+ config.file_set do |style|
98
+ style.max_code_lines_in_method 3
99
+ style.trailing_newlines 0
100
+ end
101
+ end
102
+ """
103
+ And <File> exists without a newline at the end
90
104
  When I run `tailor -d -c .tailor <File>`
91
105
  Then the output should match /Total Problems.*0/
92
106
  And the exit status should be 0
@@ -100,7 +114,15 @@ Feature: Vertical spacing
100
114
 
101
115
  @multi_line
102
116
  Scenario Outline: Lines with bad spacing around parens
103
- Given <File> exists without a newline at the end
117
+ Given my configuration file ".tailor" looks like:
118
+ """
119
+ Tailor.config do |config|
120
+ config.file_set do |style|
121
+ style.max_code_lines_in_method 3
122
+ end
123
+ end
124
+ """
125
+ And <File> exists without a newline at the end
104
126
  When I run `tailor -d -c .tailor <File>`
105
127
  Then the output should match /Total Problems.*<Problems>/
106
128
  And the output should match /position: <Position>/
@@ -111,4 +133,3 @@ Feature: Vertical spacing
111
133
  | File | Position | Position 2 | Problems |
112
134
  | v_spacing/1/method_too_long | 1:0 | | 1 |
113
135
  | v_spacing/1/parent_method_too_long | 1:0 | | 1 |
114
-
@@ -2,4 +2,16 @@ require 'term/ansicolor'
2
2
 
3
3
  class String
4
4
  include Term::ANSIColor
5
+
6
+ # Borrowed from ActiveSupport, this converts camel-case Strings to
7
+ # snake-case.
8
+ #
9
+ # @return [String]
10
+ def underscore
11
+ self.gsub(/::/, '/').
12
+ gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
13
+ gsub(/([a-z\d])([A-Z])/, '\1_\2').
14
+ tr("-", "_").
15
+ downcase
16
+ end
5
17
  end
data/lib/tailor/cli.rb CHANGED
@@ -6,8 +6,8 @@ require_relative 'reporter'
6
6
 
7
7
  class Tailor
8
8
 
9
- # The Command-Line Interface worker. Execution from the command line should
10
- # come through here.
9
+ # The Command-Line Interface worker. Execution from the command line
10
+ # comes through here.
11
11
  class CLI
12
12
  include LogSwitch::Mixin
13
13
 
@@ -16,6 +16,7 @@ class Tailor
16
16
  new(args).execute!
17
17
  end
18
18
 
19
+ # @param [Array] args Arguments from the command-line.
19
20
  def initialize(args)
20
21
  Tailor::Logger.log = false
21
22
  options = Options.parse!(args)
@@ -25,19 +26,20 @@ class Tailor
25
26
 
26
27
  if options.show_config
27
28
  @configuration.show
29
+ exit
28
30
  end
29
31
 
30
- @critic = Critic.new(@configuration.file_sets)
32
+ @critic = Critic.new
31
33
  @reporter = Reporter.new(@configuration.formatters)
32
34
  end
33
35
 
34
36
  # This checks all of the files detected during the configuration gathering
35
- # process, then hands results over to the {Reporter} to be reported.
37
+ # process, then hands results over to the {Tailor::Reporter} to be reported.
36
38
  #
37
39
  # @return [Boolean] +true+ if no problems were detected; false if there
38
40
  # were.
39
41
  def execute!
40
- @critic.critique do |problems_for_file, label|
42
+ @critic.critique(@configuration.file_sets) do |problems_for_file, label|
41
43
  @reporter.file_report(problems_for_file, label)
42
44
  end
43
45
 
@@ -19,8 +19,8 @@ class Tailor
19
19
 
20
20
  opts = OptionParser.new do |opt|
21
21
  opt.banner = self.banner
22
-
23
22
  opt.separator ""
23
+ opt.separator " " + ("-" * 73)
24
24
  opt.separator ""
25
25
  opt.separator "Config file options:"
26
26
  opt.on('-s', '--show-config', 'Show your current config.') do
@@ -35,7 +35,7 @@ class Tailor
35
35
  opt.on('--create-config', 'Create a new .tailor file') do
36
36
  if create_config
37
37
  msg = "Your new tailor config file was created at "
38
- msg << "#{Dir.pwd}."
38
+ msg << "#{Dir.pwd}/.tailor"
39
39
  $stdout.puts msg
40
40
  exit
41
41
  else
@@ -167,9 +167,11 @@ class Tailor
167
167
  opt.separator ""
168
168
  opt.separator "Common options:"
169
169
 
170
+ =begin
170
171
  opt.on('-f', '--format FORMATTER') do |format|
171
172
  options.formatters << format
172
173
  end
174
+ =end
173
175
 
174
176
  opt.on('--[no-]color', "Output in color") do |color|
175
177
  @output_color = color
@@ -229,7 +231,15 @@ class Tailor
229
231
 
230
232
  # @return [String]
231
233
  def self.usage
232
- " Usage: tailor [FILE|DIR]"
234
+ <<-USAGE
235
+ Usage: tailor [options] [FILE|DIR|GLOB]
236
+
237
+ Examples:
238
+ tailor
239
+ tailor --no-color -d my_file.rb
240
+ tailor --config-file tailor_config lib/**/*.rb
241
+ tailor --show-config
242
+ USAGE
233
243
  end
234
244
 
235
245
  def self.create_config
@@ -1,5 +1,18 @@
1
1
  class Tailor
2
+
3
+ # Used by {Tailor::Lexer} to provide publishing methods for observers.
4
+ # Any Ruler that wants to subscribe to Lexer events must use the methods
5
+ # defined here.
2
6
  module CompositeObservable
7
+
8
+ # Defines three instance methods that provide for observing a
9
+ # {Tailor::Lexer} object. If +name+ was passed "test":
10
+ #
11
+ # * +#add_test_observer+
12
+ # * +#test_update+
13
+ # * +#notify_test_observers+
14
+ #
15
+ # @param [String] name The name of event to observe/subscribe to.
3
16
  def self.define_observer(name)
4
17
  define_method("add_#{name}_observer") do |observer|
5
18
  @notifiers = {} unless defined? @notifiers
@@ -8,7 +21,8 @@ class Tailor
8
21
  call_back = "#{name}_update".to_sym
9
22
 
10
23
  unless observer.respond_to? call_back
11
- raise NoMethodError, "observer does not respond to '#{call_back}'"
24
+ raise NoMethodError,
25
+ "observer '#{observer}' does not respond to '#{call_back}'"
12
26
  end
13
27
 
14
28
  @notifiers[name][observer] = call_back
@@ -37,7 +51,8 @@ class Tailor
37
51
  define_observer :const
38
52
  define_observer :embexpr_beg
39
53
  define_observer :embexpr_end
40
- define_observer :file
54
+ define_observer :file_beg
55
+ define_observer :file_end
41
56
  define_observer :ident
42
57
  define_observer :ignored_nl
43
58
  define_observer :kw
@@ -1,6 +1,7 @@
1
1
  require_relative '../tailor'
2
- require_relative 'runtime_error'
3
2
  require_relative 'logger'
3
+ require_relative 'runtime_error'
4
+ require_relative 'configuration/style'
4
5
 
5
6
  class Tailor
6
7
 
@@ -17,27 +18,6 @@ class Tailor
17
18
  DEFAULT_GLOB = 'lib/**/*.rb'
18
19
  DEFAULT_RC_FILE = Dir.home + '/.tailorrc'
19
20
  DEFAULT_PROJECT_CONFIG = Dir.pwd + '/.tailor'
20
- DEFAULT_STYLE = {
21
- allow_camel_case_methods: false,
22
- allow_hard_tabs: false,
23
- allow_screaming_snake_case_classes: false,
24
- allow_trailing_line_spaces: false,
25
- indentation_spaces: 2,
26
- max_code_lines_in_class: 300,
27
- max_code_lines_in_method: 30,
28
- max_line_length: 80,
29
- spaces_after_comma: 1,
30
- spaces_before_comma: 0,
31
- spaces_before_lbrace: 1,
32
- spaces_after_lbrace: 1,
33
- spaces_before_rbrace: 1,
34
- spaces_in_empty_braces: 0,
35
- spaces_after_lbracket: 0,
36
- spaces_before_rbracket: 0,
37
- spaces_after_lparen: 0,
38
- spaces_before_rparen: 0,
39
- trailing_newlines: 1
40
- }
41
21
 
42
22
  # @return [Hash]
43
23
  def self.default
@@ -53,11 +33,12 @@ class Tailor
53
33
  # @option options [Array] formatters
54
34
  # @option options [Hash] style
55
35
  def initialize(runtime_file_list=nil, options=nil)
36
+ @style = Style.new
56
37
  @formatters = ['text']
57
38
  @file_sets = {
58
39
  default: {
59
40
  file_list: file_list(DEFAULT_GLOB),
60
- style: DEFAULT_STYLE
41
+ style: @style.to_hash
61
42
  }
62
43
  }
63
44
 
@@ -75,48 +56,72 @@ class Tailor
75
56
 
76
57
  if @config_file
77
58
  if @rc_file_config
78
- # Get formatters from config file
79
- unless @rc_file_config.formatters.empty?
80
- @formatters = @rc_file_config.formatters
81
- log "@formatters is now #{@formatters}"
82
- end
59
+ get_formatters_from_config_file
60
+ get_files_sets_from_config_file
61
+ end
62
+ end
63
+
64
+ get_formatters_from_cli_opts
65
+ get_files_sets_from_cli_opts
66
+ get_style_from_cli_opts
67
+
68
+ if @file_sets[:default][:file_list].empty?
69
+ @file_sets[:default][:file_list] = file_list(DEFAULT_GLOB)
70
+ end
71
+ end
72
+
73
+ def get_files_sets_from_config_file
74
+ unless @rc_file_config.file_sets.empty?
75
+ @rc_file_config.file_sets.each do |label, file_set|
76
+ log "file set: #{file_set}"
83
77
 
84
- # Get file sets from config file
85
- unless @rc_file_config.file_sets.empty?
86
- @rc_file_config.file_sets.each do |label, file_set|
87
- unless @file_sets[label]
88
- @file_sets[label] = { style: DEFAULT_STYLE }
89
- end
90
-
91
- @file_sets[label][:file_list].concat file_set[:file_list]
92
- @file_sets[label][:file_list].uniq!
93
- @file_sets[label][:style].merge! file_set[:style]
94
- end
78
+ if @file_sets[label]
79
+ @file_sets[label][:file_list].concat file_set[:file_list]
80
+ @file_sets[label][:file_list].uniq!
81
+ @file_sets[label][:style].merge! file_set[:style]
82
+ else
83
+ @file_sets[label] = {
84
+ file_list: file_set[:file_list],
85
+ style: @style.to_hash.merge(file_set[:style])
86
+ }
95
87
  end
96
88
  end
97
89
  end
90
+ end
98
91
 
99
- # Get formatters from CLI options
100
- unless @options.formatters.empty? || @options.formatters.nil?
101
- @formatters = @options.formatters
92
+ def get_formatters_from_config_file
93
+ unless @rc_file_config.formatters.empty?
94
+ @formatters = @rc_file_config.formatters
102
95
  log "@formatters is now #{@formatters}"
103
96
  end
97
+ end
98
+
99
+ def get_style_from_cli_opts
100
+ if @options.style
101
+ @options.style.each do |property, value|
102
+ if value == :off || value == "off"
103
+ @file_sets[:default][:style][property][1] = { level: :off }
104
+ else
105
+ @file_sets[:default][:style][property][0] = value
106
+ end
107
+ end
108
+ end
109
+ end
104
110
 
105
- # Get file sets from CLI options
111
+ def get_files_sets_from_cli_opts
106
112
  unless @runtime_file_list.nil? || @runtime_file_list.empty?
107
113
  # Only use options set for the :default file set because the user gave
108
114
  # a different set of files to measure.
109
115
  @file_sets.delete_if { |k, v| k != :default }
110
116
  @file_sets[:default][:file_list] = file_list(@runtime_file_list)
111
117
  end
118
+ end
112
119
 
113
- # Get style overrides from CLI options
114
- @file_sets[:default][:style].merge!(@options.style)
115
-
116
- if @file_sets[:default][:file_list].empty?
117
- @file_sets[:default][:file_list] = file_list(DEFAULT_GLOB)
120
+ def get_formatters_from_cli_opts
121
+ unless @options.formatters.empty? || @options.formatters.nil?
122
+ @formatters = @options.formatters
123
+ log "@formatters is now #{@formatters}"
118
124
  end
119
-
120
125
  end
121
126
 
122
127
  # @return [String] Name of the config file to use.
@@ -139,42 +144,36 @@ class Tailor
139
144
  @formatters
140
145
  end
141
146
 
147
+ # Adds a file set to the list of file sets in the Configuration object.
148
+ #
142
149
  # @param [String] file_glob The String that represents the file set. This
143
150
  # can be a file, directory, or a glob.
144
151
  # @param [Symbol] label The label that represents the file set.
145
- def file_set(file_glob=DEFAULT_GLOB, label=:default, &block)
152
+ def file_set(file_glob=DEFAULT_GLOB, label=:default)
153
+ log "file sets before: #{@file_sets}"
146
154
  log "file set label #{label}"
147
155
 
148
- @temp_style = {}
149
- instance_eval(&block) if block_given?
156
+ new_style = Style.new
157
+
158
+ if block_given?
159
+ yield new_style
160
+
161
+ if @file_sets[label]
162
+ @file_sets[label][:style].merge! new_style
163
+ end
164
+ end
150
165
 
151
166
  if @file_sets[label]
152
167
  @file_sets[label][:file_list].concat file_list(file_glob)
153
- log "file set: #{@file_sets}"
154
168
  @file_sets[label][:file_list].uniq!
155
- @file_sets[label][:style].merge @temp_style
156
169
  else
157
170
  @file_sets[label] = {
158
171
  file_list: file_list(file_glob),
159
- style: DEFAULT_STYLE.merge(@temp_style)
172
+ style: @style.to_hash.merge(new_style)
160
173
  }
161
174
  end
162
175
 
163
- @temp_style = {}
164
- end
165
-
166
- # Implemented for {file_set}, this converts the config file lines that look
167
- # like methods into a Hash.
168
- #
169
- # @return [Hash] The new style as defined by the config file.
170
- def method_missing(meth, *args, &blk)
171
- ok_methods = DEFAULT_STYLE.keys
172
-
173
- if ok_methods.include? meth
174
- @temp_style[meth] = args.first
175
- else
176
- super(meth, args, blk)
177
- end
176
+ log "file sets after: #{@file_sets}"
178
177
  end
179
178
 
180
179
  # Tries to open the file at the path given at +config_file+ and read in
@@ -186,6 +185,7 @@ class Tailor
186
185
 
187
186
  if File.exists? user_config_file
188
187
  log "Loading config from file: #{user_config_file}"
188
+
189
189
  begin
190
190
  config = instance_eval File.read(user_config_file)
191
191
  rescue LoadError => ex
@@ -248,14 +248,25 @@ class Tailor
248
248
  list_with_absolute_paths.sort
249
249
  end
250
250
 
251
+ # Displays the current configuration as a text table.
251
252
  def show
252
253
  table = Text::Table.new(horizontal_padding: 4)
253
254
  table.head = [{ value: 'Configuration', colspan: 2, align: :center }]
254
255
  table.rows << :separator
255
- table.rows << ['Style', @file_sets.inspect]
256
- table.rows << :separator
257
256
  table.rows << ['Formatters', @formatters]
258
257
 
258
+ @file_sets.each do |label, file_set|
259
+ table.rows << :separator
260
+ table.rows << ['Label', label]
261
+ table.rows << ['Style', '']
262
+ file_set[:style].each do |k, v|
263
+ table.rows << ['', "#{k}: #{v}"]
264
+ end
265
+
266
+ table.rows << ['File List', '']
267
+ file_set[:file_list].each { |file| table.rows << ['', file] }
268
+ end
269
+
259
270
  puts table
260
271
  end
261
272
  end