greener 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 82d715e2bc60c20c81addaf628e6261ce71fe7b3
4
- data.tar.gz: 0a8b92e22438005651b5e3ac73106b784ea9f046
3
+ metadata.gz: 1d98afd17cecb377e1bdc8e8298db1bec22e8376
4
+ data.tar.gz: f60f7de29eb95eee30d8ca8c8553cc789baabd1a
5
5
  SHA512:
6
- metadata.gz: 7fdfa149aa9569cd11b86f02529a2c420b2561d701454eaedc9a24c9a3dba26bba1df53053d086cb0daea573e88814d67a8596af9a636d86a1763a5f6f9c0ccf
7
- data.tar.gz: cc534b77ef04bc747d542cc353fd22bcc9f54d5f9dac3c8d0cf95511d2b51f163b0875a82d56475b54dbb9db6e3d92bae3f32e06cdea36b1390611a9b2a4fc05
6
+ metadata.gz: 96a060c2754ad72b3a6c6e76f05630923f494d94420731f755e22502dafdaa1cf7c0c432e57b94a74033af7b64a92411772c3799c9b0d379d83f3bec6dd924da
7
+ data.tar.gz: 879d811ead5670aa08989db2de52487dfee7dff422fe3c93d7d8a14f7abd8222b1a0676b468e8ec12fd1ddbea0c690b77129cf3274642445b6f25e400b5d6388
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
- greener
1
+ Greener
2
2
  ===
3
3
 
4
- [![Circle CI](https://circleci.com/gh/smoll/greener.svg?style=svg)](https://circleci.com/gh/smoll/greener) [![Code Climate](https://codeclimate.com/github/smoll/greener/badges/gpa.svg)](https://codeclimate.com/github/smoll/greener) [![Coverage Status](https://coveralls.io/repos/smoll/greener/badge.svg?branch=master)](https://coveralls.io/r/smoll/greener?branch=master) [![Gem Version](https://badge.fury.io/rb/greener.svg)](http://badge.fury.io/rb/greener)
4
+ [![Circle CI](https://circleci.com/gh/smoll/greener.svg?style=svg)](https://circleci.com/gh/smoll/greener) [![Code Climate](https://codeclimate.com/github/smoll/greener/badges/gpa.svg)](https://codeclimate.com/github/smoll/greener) [![Coverage Status](https://coveralls.io/repos/smoll/greener/badge.svg?branch=master)](https://coveralls.io/r/smoll/greener?branch=master) [![Gem Version](https://badge.fury.io/rb/greener.svg)](http://badge.fury.io/rb/greener) [![Inline docs](http://inch-ci.org/github/smoll/greener.svg?branch=master)](http://inch-ci.org/github/smoll/greener)
5
5
 
6
- A Gherkin .feature file linter
6
+ Keep your Cucumber and Spinach feature files greener :four_leaf_clover: with this configurable linter
7
7
 
8
8
  **NOTE: This project is still under early-stage development**
9
9
 
@@ -1,8 +1,12 @@
1
- # AllCheckers:
2
- # Include:
3
- # - "**/*.feature"
4
- # Exclude:
5
- # - "**/*_exclusionary_special.feature"
1
+ AllCheckers:
2
+ Formatters:
3
+ # Summary does not need to be added here explicitly
4
+ - Progress
5
+ - SimpleText
6
+ Include:
7
+ - "**/*.feature"
8
+ # Exclude:
9
+ # - "some/excluded/path/*.feature"
6
10
 
7
11
  Style/FeatureName:
8
12
  Enabled: true
@@ -8,6 +8,8 @@ Feature: (checker) feature name
8
8
  When I run `greener`
9
9
  Then the output should contain:
10
10
  """
11
+ F
12
+
11
13
  foo/mismatched_feature_title.feature:1
12
14
  Feature: mismatched feature title LOL
13
15
  ^^^ feature title does not match file name
@@ -21,7 +23,12 @@ Feature: (checker) feature name
21
23
  Feature: Valid Title
22
24
  """
23
25
  When I run `greener`
24
- Then the output should contain exactly "1 file(s) inspected, no offenses detected\n"
26
+ Then the output should contain:
27
+ """
28
+ .
29
+
30
+ 1 file(s) inspected, no offenses detected
31
+ """
25
32
 
26
33
  Scenario: punctuation allowed
27
34
  Given a file named "foo/some_punctuation.feature" with:
@@ -35,7 +42,12 @@ Feature: (checker) feature name
35
42
  AllowPunctuation: true
36
43
  """
37
44
  When I run `greener --config config/punctuation_allowed.yml`
38
- Then the output should contain exactly "1 file(s) inspected, no offenses detected\n"
45
+ Then the output should contain:
46
+ """
47
+ .
48
+
49
+ 1 file(s) inspected, no offenses detected
50
+ """
39
51
 
40
52
  Scenario: title case enforced
41
53
  Given a file named "foo/this_isnt_title_case_yo.feature" with:
@@ -52,6 +64,8 @@ Feature: (checker) feature name
52
64
  When I run `greener --config config/enforce_title_case.yml`
53
65
  Then the output should contain:
54
66
  """
67
+ F
68
+
55
69
  foo/this_isnt_title_case_yo.feature:1
56
70
  Feature: this isn't Title Case, yo!
57
71
  ^^^ feature title is not title case. expected: This Isn't Title Case, Yo!
@@ -13,6 +13,8 @@ Feature: (checker) indentation width
13
13
  When I run `greener`
14
14
  Then the output should contain:
15
15
  """
16
+ F
17
+
16
18
  foo/indentation.feature:5
17
19
  Scenario: poorly indented
18
20
  ^^^ inconsistent indentation detected
@@ -11,7 +11,12 @@ Feature: configuration
11
11
  Enabled: false
12
12
  """
13
13
  When I run `greener --config config/disabled.yml`
14
- Then the output should contain exactly "1 file(s) inspected, no offenses detected\n"
14
+ Then the output should contain:
15
+ """
16
+ .
17
+
18
+ 1 file(s) inspected, no offenses detected
19
+ """
15
20
 
16
21
  Scenario: invalid checker specified in config
17
22
  Given a file named "foo/something.feature" with:
@@ -46,4 +51,9 @@ Feature: configuration
46
51
  Width: 4
47
52
  """
48
53
  When I run `greener --config config/complex.yml`
49
- Then the output should contain exactly "1 file(s) inspected, no offenses detected\n"
54
+ Then the output should contain:
55
+ """
56
+ .
57
+
58
+ 1 file(s) inspected, no offenses detected
59
+ """
@@ -0,0 +1,34 @@
1
+ Feature: (formatter) progress
2
+
3
+ Scenario: happy path
4
+ Given a file named "foo/good.feature" with:
5
+ """
6
+ Feature: good
7
+
8
+ Scenario: correctly indented
9
+
10
+ Scenario: correctly indented
11
+ Then boom
12
+ """
13
+ Given a file named "foo/good_too.feature" with:
14
+ """
15
+ Feature: good too
16
+
17
+ Scenario: correctly indented
18
+
19
+ Scenario: correctly indented
20
+ Then boom
21
+ """
22
+ And a file named "config/good.yml" with:
23
+ """
24
+ AllCheckers:
25
+ Formatters:
26
+ - Progress
27
+ """
28
+ When I run `greener --config config/good.yml`
29
+ Then the output should contain:
30
+ """
31
+ ..
32
+
33
+ 2 file(s) inspected, no offenses detected
34
+ """
@@ -13,6 +13,8 @@ Feature: lint
13
13
  When I run `greener`
14
14
  Then the output should contain:
15
15
  """
16
+ F
17
+
16
18
  foo/multiple_issues.feature:1
17
19
  Feature: multiple issues
18
20
  ^^^ inconsistent indentation detected
@@ -31,8 +31,7 @@ Gem::Specification.new do |spec|
31
31
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
32
32
  spec.require_paths = ["lib"]
33
33
 
34
- # TODO: rip this out when gherkin3 has a release
35
- spec.add_dependency "gherkin3-pre-alpha", "~> 3.0.0.alpha.1"
34
+ spec.add_dependency "gherkin", "~> 4.0.0"
36
35
  spec.add_dependency "thor", "~> 0.19.1"
37
36
  spec.add_dependency "titleize", "~> 1.3.0"
38
37
 
@@ -21,7 +21,8 @@ module Greener
21
21
  end
22
22
 
23
23
  def check_every_scenario
24
- feature[:scenarioDefinitions].each do |scenario|
24
+ scenarios = feature[:scenarioDefinitions] || feature[:children]
25
+ scenarios.each do |scenario|
25
26
  scenario[:steps].each { |step| check_a_step(step) }
26
27
 
27
28
  next if scenario[:location][:column] == (1 + configured_indentation_width)
@@ -12,7 +12,6 @@ module Greener
12
12
  def lint
13
13
  linter = Linter.new(options[:config])
14
14
  linter.lint
15
- linter.print_results
16
15
  end
17
16
 
18
17
  default_task :lint
@@ -1,18 +1,23 @@
1
1
  require "yaml"
2
2
 
3
3
  require "greener/utils"
4
- require "greener/custom_error"
4
+ require "greener/error"
5
5
 
6
6
  # Require all checker files here
7
7
  require "greener/checker/style/feature_name"
8
8
  require "greener/checker/style/indentation_width"
9
9
 
10
+ # And formatters
11
+ require "greener/formatter/progress"
12
+ require "greener/formatter/simple_text"
13
+ require "greener/formatter/summary"
14
+
10
15
  module Greener
11
16
  # Read configs from a user-specified greener.yml or fallback to defaults
12
17
  class ConfigStore
13
18
  include Utils
14
19
 
15
- attr_reader :checkers, :files
20
+ attr_reader :checkers, :files, :formatters
16
21
 
17
22
  def initialize(path, default_path = nil)
18
23
  @path = path
@@ -21,16 +26,18 @@ module Greener
21
26
 
22
27
  @checkers = {}
23
28
  @files = []
29
+ @formatters = []
24
30
  end
25
31
 
26
32
  def resolve
27
33
  if @path
28
- fail CustomError, "No config file found at specified path: #{@path}" unless File.exist? @path
34
+ fail Error::Standard, "No config file found at specified path: #{@path}" unless File.exist? @path
29
35
  config = load_yml_file @path
30
36
  end
31
- defaults = load_yml_file @default_path
32
37
 
33
- @all = @path ? defaults.merge(config) : defaults
38
+ config ||= {}
39
+ defaults = load_yml_file @default_path
40
+ @all = merge_hashes(defaults, config)
34
41
 
35
42
  validate
36
43
  self
@@ -47,15 +54,47 @@ module Greener
47
54
 
48
55
  private
49
56
 
57
+ # Deep merge, with a few post-merge checks
58
+ def merge_hashes(default, opt)
59
+ result = deep_merge(default, opt)
60
+ # Change nils to empty hashes/arrays so this class isn't littered with #nil? checks
61
+ result["AllCheckers"]["Exclude"] = [] if result["AllCheckers"]["Exclude"].nil?
62
+
63
+ result
64
+ end
65
+
66
+ def deep_merge(first, second)
67
+ merger = proc { |_key, v1, v2| v1.is_a?(Hash) && v2.is_a?(Hash) ? v1.merge(v2, &merger) : v2 }
68
+ first.merge(second, &merger)
69
+ end
70
+
50
71
  def validate
72
+ set_formatters
51
73
  set_checkers
52
74
  set_files
53
75
 
76
+ @all.delete("AllCheckers") if @all["AllCheckers"] && @all["AllCheckers"].empty?
77
+
54
78
  @all.each do |k, _v|
55
- fail CustomError, "Unknown option in config file: #{k}" # TODO: print warning instead of fail
79
+ fail Error::Standard, "Unknown option in config file: #{k}" # TODO: print warning instead of fail
56
80
  end
57
81
  end
58
82
 
83
+ def set_formatters
84
+ formatters = @all["AllCheckers"]["Formatters"].uniq.compact
85
+ # Ensure "Summary" formatter is in last position
86
+ if formatters.include?("Summary")
87
+ formatters << formatters.delete("Summary")
88
+ else
89
+ formatters << "Summary"
90
+ end
91
+ formatters.each do |f_string|
92
+ @formatters << formatter_from_string(f_string)
93
+ end
94
+
95
+ @all["AllCheckers"].delete "Formatters"
96
+ end
97
+
59
98
  def set_checkers
60
99
  @all.each do |k, v|
61
100
  next unless %w( Style/ Lint/ ).any? { |prefix| k.start_with?(prefix) }
@@ -66,25 +105,16 @@ module Greener
66
105
  end
67
106
 
68
107
  def set_files
69
- if @all["AllCheckers"].nil?
70
- # Default to all .feature files recursively
71
- return @files = files_matching_glob("**/*.feature")
72
- end
73
-
74
- @all.each do |k, v|
75
- next unless k == "AllCheckers"
76
- discover_files(v)
77
- @all.delete(k)
78
- end
79
- end
80
-
81
- def discover_files(hash)
82
108
  includes = []
83
109
  excludes = []
84
110
 
85
- hash["Include"].each { |glob| includes += files_matching_glob(glob) } if hash["Include"]
86
- hash["Exclude"].each { |glob| excludes += files_matching_glob(glob) } if hash["Exclude"]
87
- @files = (includes - excludes).uniq
111
+ @all["AllCheckers"]["Include"].each { |glob| includes += files_matching_glob(glob) }
112
+ @all["AllCheckers"].delete "Include"
113
+
114
+ @all["AllCheckers"]["Exclude"].each { |glob| excludes += files_matching_glob(glob) }
115
+ @all["AllCheckers"].delete "Exclude"
116
+
117
+ @files = includes.uniq - excludes.uniq
88
118
  end
89
119
 
90
120
  def default_absolute_path
@@ -0,0 +1,7 @@
1
+ module Greener
2
+ module Error
3
+ class Standard < StandardError; end
4
+
5
+ class LintFailed < Standard; end
6
+ end
7
+ end
@@ -0,0 +1,35 @@
1
+ module Greener
2
+ module Formatter
3
+ # Abstract base class for formatter, implements all public API methods.
4
+ #
5
+ # ## Method Invocation Order
6
+ #
7
+ # For example, when Greener inspects 2 files,
8
+ # the invocation order should be like this:
9
+ #
10
+ # * `#initialize`
11
+ # * `#started`
12
+ # * `#file_started`
13
+ # * `#file_finished`
14
+ # * `#file_started`
15
+ # * `#file_finished`
16
+ # * `#finished`
17
+ class BaseFormatter
18
+ def initialize(files)
19
+ @files = files
20
+ end
21
+
22
+ def started
23
+ end
24
+
25
+ def file_started
26
+ end
27
+
28
+ def file_finished(_violations)
29
+ end
30
+
31
+ def finished(_violations)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ require "greener/formatter/base_formatter"
2
+
3
+ module Greener
4
+ module Formatter
5
+ # Print progress in real-time
6
+ class Progress < BaseFormatter
7
+ def file_finished(violations)
8
+ if violations.empty?
9
+ print "."
10
+ else
11
+ print "F"
12
+ end
13
+ end
14
+
15
+ def finished(_violations)
16
+ puts ""
17
+ puts ""
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ require "greener/formatter/base_formatter"
2
+
3
+ module Greener
4
+ module Formatter
5
+ # Prints violation info that includes file, line number, text of the line, and message
6
+ class SimpleText < BaseFormatter
7
+ def finished(violations)
8
+ violations.each do |violation|
9
+ puts "#{violation[:file]}:#{violation[:line]}"
10
+ puts "#{violation[:text_of_line]}"
11
+ puts "#{' ' * (violation[:column] - 1)}^^^ #{violation[:message]}"
12
+ puts ""
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ require "greener/formatter/base_formatter"
2
+
3
+ module Greener
4
+ module Formatter
5
+ # Prints summary line, e.g. "10 file(s) inspected, no offenses detected"
6
+ class Summary < BaseFormatter
7
+ def finished(violations)
8
+ conclusion = violations.empty? ? "no offenses detected" : "#{violations.count} offense(s) detected"
9
+
10
+ res = "#{@files.count} file(s) inspected, #{conclusion}"
11
+ return puts(res) if violations.empty?
12
+ fail Greener::Error::LintFailed, res
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,20 @@
1
+ module Greener
2
+ # A set of Greener::Formatter::SomeFormatter objects
3
+ class FormatterSet
4
+ def initialize(formatters)
5
+ @formatters = formatters
6
+ end
7
+
8
+ # Note the "d"
9
+ def initialized(*args)
10
+ @formatters = @formatters.map { |formatter| formatter.new(*args) }
11
+ end
12
+
13
+ # All these instance methods have the same method signature as those of the Formatter classes
14
+ [:started, :file_started, :file_finished, :finished].each do |method_name|
15
+ define_method method_name do |*args|
16
+ @formatters.each { |formatter| formatter.send(method_name, *args) }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,9 +1,6 @@
1
- require "gherkin3/parser"
2
- require "gherkin3/token_scanner"
3
- require "gherkin3/ast_builder"
4
- require "gherkin3/token_matcher"
5
-
6
1
  require "greener/config_store"
2
+ require "greener/formatter_set"
3
+ require "greener/parser"
7
4
 
8
5
  module Greener
9
6
  # Parse then lint a collection of .feature files for violations
@@ -11,49 +8,42 @@ module Greener
11
8
  def initialize(config_path)
12
9
  @config = ConfigStore.new(config_path).resolve
13
10
  @results = []
11
+ @formatter_set = FormatterSet.new @config.formatters
14
12
  end
15
13
 
16
- # Here we iterate through a list of files, then iterate through the list of
17
- # desired checkers, passing each one the filename & parsed AST.
18
- # This is fine for now, but to speed this up we could refactor this to do a
19
- # single pass through the file, line-by-line, and flagging violations as
20
- # they are encountered.
21
14
  def lint
22
- @config.files.each { |f| parse_single_file(f) }
23
- end
24
-
25
- def print_results
26
- @results.each do |violation|
27
- puts "#{violation[:file]}:#{violation[:line]}"
28
- puts "#{violation[:text_of_line]}"
29
- puts "#{' ' * (violation[:column] - 1)}^^^ #{violation[:message]}"
30
- puts ""
15
+ @formatter_set.initialized(@config.files)
16
+ @formatter_set.started
17
+
18
+ # Here we iterate through a list of files, then iterate through the list of
19
+ # desired checkers, passing each one the filename & parsed AST.
20
+ # This is fine for now, but to speed this up we could refactor this to do a
21
+ # single pass through the file, line-by-line, and flagging violations as
22
+ # they are encountered.
23
+ @config.files.each do |f|
24
+ process_file(f) # TODO: move this to its own class
31
25
  end
32
26
 
33
- print_final_line
27
+ @formatter_set.finished @results
34
28
  end
35
29
 
36
30
  private
37
31
 
38
- def parse_single_file(fname)
39
- parser = Gherkin3::Parser.new
40
- scanner = Gherkin3::TokenScanner.new(fname)
41
- builder = Gherkin3::AstBuilder.new
42
- ast = parser.parse(scanner, builder, Gherkin3::TokenMatcher.new)
32
+ def process_file(fname)
33
+ @formatter_set.file_started
34
+
35
+ ast = Parser.new(fname).ast
36
+
37
+ violations_in_file = []
43
38
 
44
39
  @config.checkers.each do |sc_klass, sc_opts|
45
40
  checker = sc_klass.new(ast, fname, sc_opts)
46
41
  checker.run
42
+ violations_in_file += checker.violations
47
43
  @results += checker.violations
48
44
  end
49
- end
50
-
51
- def print_final_line
52
- conclusion = @results.empty? ? "no offenses detected" : "#{@results.count} offense(s) detected"
53
45
 
54
- res = "#{@config.files.count} file(s) inspected, #{conclusion}"
55
- return puts(res) if @results.empty?
56
- fail Greener::Error::LintFailed, res
46
+ @formatter_set.file_finished(violations_in_file)
57
47
  end
58
48
  end
59
49
  end
@@ -0,0 +1,35 @@
1
+ require "stringio"
2
+
3
+ module Greener
4
+ # Initialize this class to delay output, https://gist.github.com/macek/596007
5
+ class OutputBuffer
6
+ def initialize
7
+ @buffer = StringIO.new
8
+ activate
9
+ end
10
+
11
+ def activate
12
+ return if @activated
13
+ self.class.original_stdout = $stdout
14
+ $stdout = @buffer
15
+ @activated = true
16
+ end
17
+
18
+ def to_s
19
+ @buffer.rewind
20
+ @buffer.read
21
+ end
22
+
23
+ def stop
24
+ self.class.restore_default
25
+ end
26
+
27
+ class << self
28
+ attr_accessor :original_stdout
29
+
30
+ def restore_default
31
+ $stdout = original_stdout
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ require "gherkin/parser"
2
+ require "gherkin/token_scanner"
3
+
4
+ module Greener
5
+ # Wrapper around Gherkin3's Parser
6
+ class Parser
7
+ def initialize(feature)
8
+ @feature = feature # filepath or String
9
+ end
10
+
11
+ # Return an Abstract Syntax Tree from a feature file
12
+ def ast
13
+ parser = Gherkin::Parser.new
14
+ if @feature.include?("Feature:")
15
+ parser.parse(Gherkin::TokenScanner.new(@feature))
16
+ else
17
+ parser.parse(Gherkin::TokenScanner.new(File.read(@feature)))[:feature]
18
+ end
19
+ end
20
+ end
21
+ end
@@ -30,7 +30,7 @@ module Greener
30
30
 
31
31
  # Thor::Base#start does not have a return value, assume success if no exception is raised.
32
32
  0
33
- rescue Greener::CustomError => e
33
+ rescue Greener::Error::Standard => e
34
34
  @stderr.puts e.message
35
35
  1
36
36
  rescue StandardError => e
@@ -5,7 +5,13 @@ module Greener
5
5
  namespaced = str.gsub("/", "::")
6
6
  constantize "Greener::Checker::#{namespaced}"
7
7
  rescue NameError
8
- raise CustomError, "Unknown checker specified: #{str}" # TODO: print warning instead of failing
8
+ raise Error::Standard, "Unknown checker specified: #{str}" # TODO: print warning instead of failing
9
+ end
10
+
11
+ def formatter_from_string(str)
12
+ constantize "Greener::Formatter::#{str}"
13
+ rescue NameError
14
+ raise Error::Standard, "Unknown formatter specified: #{str}" # TODO: print warning instead of failing
9
15
  end
10
16
 
11
17
  private
@@ -1,4 +1,4 @@
1
1
  # Gem version
2
2
  module Greener
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: greener
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - smoll
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-29 00:00:00.000000000 Z
11
+ date: 2018-03-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: gherkin3-pre-alpha
14
+ name: gherkin
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 3.0.0.alpha.1
19
+ version: 4.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 3.0.0.alpha.1
26
+ version: 4.0.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: thor
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -181,6 +181,7 @@ files:
181
181
  - features/checker_feature_name.feature
182
182
  - features/checker_indentation_width.feature
183
183
  - features/configuration.feature
184
+ - features/formatter_progress.feature
184
185
  - features/lint.feature
185
186
  - features/support/env.rb
186
187
  - greener.gemspec
@@ -190,8 +191,15 @@ files:
190
191
  - lib/greener/checker/style/indentation_width.rb
191
192
  - lib/greener/cli.rb
192
193
  - lib/greener/config_store.rb
193
- - lib/greener/custom_error.rb
194
+ - lib/greener/error.rb
195
+ - lib/greener/formatter/base_formatter.rb
196
+ - lib/greener/formatter/progress.rb
197
+ - lib/greener/formatter/simple_text.rb
198
+ - lib/greener/formatter/summary.rb
199
+ - lib/greener/formatter_set.rb
194
200
  - lib/greener/linter.rb
201
+ - lib/greener/output_buffer.rb
202
+ - lib/greener/parser.rb
195
203
  - lib/greener/runner.rb
196
204
  - lib/greener/utils.rb
197
205
  - lib/greener/version.rb
@@ -215,7 +223,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
215
223
  version: '0'
216
224
  requirements: []
217
225
  rubyforge_project:
218
- rubygems_version: 2.4.8
226
+ rubygems_version: 2.6.13
219
227
  signing_key:
220
228
  specification_version: 4
221
229
  summary: A Gherkin .feature file linter
@@ -1,7 +0,0 @@
1
- module Greener
2
- class CustomError < StandardError; end
3
-
4
- module Error
5
- class LintFailed < Greener::CustomError; end
6
- end
7
- end