greener 0.0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a8ee00975481d14b7de2a3c4c5704e38e2ae7f8d
4
+ data.tar.gz: e3b4e819ebbd7dffba73cbcce66537534b5e1a3c
5
+ SHA512:
6
+ metadata.gz: 018e3986bb9ae95dcaf5101190865c62d562b27724639b294990252d1e2b3ee7385f5f3b0e2f4a127ac10100b2eb5f8506d47bde510d6e62dd37af89f5be4ce2
7
+ data.tar.gz: f6ffa76be7bdfbca5ac6b1586691ee5ceaaa34f9d1090015388759d602d990e8c452dcd005903826ddfc79df3acac71caf1979007fffafd47376cf54a75b9b07
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 smoll
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,61 @@
1
+ greener
2
+ ===
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)
5
+
6
+ A Gherkin .feature file linter
7
+
8
+ **NOTE: This project is still under early-stage development**
9
+
10
+ ## TODOs
11
+
12
+ 0. Move "results printing" logic to configurable formatters
13
+ 0. Implement some kind of hooks system for use by formatters, similar to [this](https://github.com/bbatsov/rubocop/blob/master/lib/rubocop/formatter/base_formatter.rb#L30-L41)
14
+ 0. Create a RakeTask class for use in CI systems
15
+ 0. Add coloring for formatters
16
+
17
+ ## Contributing
18
+
19
+ Install dev dependencies locally
20
+ ```
21
+ bundle install
22
+ ```
23
+
24
+ Run tests
25
+ ```
26
+ bundle exec rake test
27
+ ```
28
+
29
+ View code coverage
30
+ ```
31
+ rake && open coverage/index.html
32
+ ```
33
+
34
+ View code coverage from RSpec unit tests only
35
+ ```
36
+ rm -rf coverage && rspec && open coverage/index.html
37
+ ```
38
+
39
+ ## Testing
40
+
41
+ To test the `greener` binary locally, `cd` to the repo root and run
42
+ ```
43
+ RUBYLIB=lib bundle exec ruby bin/greener
44
+ ```
45
+ Based on [this answer](http://stackoverflow.com/a/23367196/3456726).
46
+
47
+ ## References
48
+
49
+ #### CLI related
50
+
51
+ 0. http://guides.rubygems.org/make-your-own-gem/
52
+ 0. http://whatisthor.com/
53
+ 0. https://github.com/erikhuda/thor/wiki/Integrating-with-Aruba-In-Process-Runs
54
+
55
+ #### Testing related
56
+ 0. http://stackoverflow.com/questions/12673485/how-to-test-stdin-for-a-cli-using-rspec
57
+ 0. https://github.com/livinginthepast/aruba-rspec
58
+
59
+ #### Lint related
60
+
61
+ 0. https://github.com/bbatsov/rubocop/tree/master/lib/rubocop
data/bin/greener ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "greener/runner"
4
+
5
+ Greener::Runner.new(ARGV.dup).execute!
@@ -0,0 +1,13 @@
1
+ # FileList:
2
+ # Include:
3
+ # - "**/*.feature"
4
+ # Exclude:
5
+ # - "**/*_exclusionary_special.feature"
6
+
7
+ Style/FeatureName:
8
+ Enabled: true
9
+
10
+ Style/IndentationWidth:
11
+ Enabled: true
12
+ # Number of spaces for each indentation level.
13
+ Width: 2
@@ -0,0 +1,4 @@
1
+ # Used by dogfood test, i.e. run greener against the .feature files in this repo!
2
+ FileList:
3
+ Include:
4
+ - "features/**/*.feature"
@@ -0,0 +1,49 @@
1
+ Feature: configuration
2
+
3
+ Scenario: disable checker via config file
4
+ Given a file named "foo/mismatched_feature_title.feature" with:
5
+ """
6
+ Feature: mismatched feature title LOL
7
+ """
8
+ And a file named "config/disabled.yml" with:
9
+ """
10
+ Style/FeatureName:
11
+ Enabled: false
12
+ """
13
+ When I run `greener --config config/disabled.yml`
14
+ Then the output should contain exactly "1 file(s) inspected, no offenses detected\n"
15
+
16
+ Scenario: invalid checker specified in config
17
+ Given a file named "foo/something.feature" with:
18
+ """
19
+ Feature: something
20
+ """
21
+ And a file named "config/invalid.yml" with:
22
+ """
23
+ Style/NotEvenReal:
24
+ Enabled: false
25
+ """
26
+ When I run `greener --config config/invalid.yml`
27
+ Then the output should contain exactly "Unknown checker specified: Style/NotEvenReal\n"
28
+
29
+ Scenario: complex configuration
30
+ Given a file named "foo/indentation_too.feature" with:
31
+ """
32
+ Feature: BAD NAME LOL
33
+
34
+ Scenario: correctly indented
35
+
36
+ Scenario: correctly indented
37
+ Then boom
38
+ """
39
+ And a file named "config/complex.yml" with:
40
+ """
41
+ Style/FeatureName:
42
+ Enabled: false
43
+
44
+ Style/IndentationWidth:
45
+ Enabled: true
46
+ Width: 4
47
+ """
48
+ When I run `greener --config config/complex.yml`
49
+ Then the output should contain exactly "1 file(s) inspected, no offenses detected\n"
@@ -0,0 +1,44 @@
1
+ Feature: lint
2
+ * TODO: eventually, move most, if not all, of these to unit tests
3
+
4
+ Scenario: feature text matches, with flexible capitalization
5
+ Given a file named "foo/valid_title.feature" with:
6
+ """
7
+ Feature: Valid Title
8
+ """
9
+ When I run `greener`
10
+ Then the output should contain exactly "1 file(s) inspected, no offenses detected\n"
11
+
12
+ Scenario: feature text does not match filename
13
+ Given a file named "foo/mismatched_feature_title.feature" with:
14
+ """
15
+ Feature: mismatched feature title LOL
16
+ """
17
+ When I run `greener`
18
+ Then the output should contain exactly "foo/mismatched_feature_title.feature:1\nFeature: mismatched feature title LOL\n^^^ feature title does not match file name\n\n1 file(s) inspected, 1 offense(s) detected\n"
19
+
20
+ Scenario: inconsistent indentation
21
+ Given a file named "foo/indentation.feature" with:
22
+ """
23
+ Feature: indentation
24
+
25
+ Scenario: correctly indented
26
+
27
+ Scenario: poorly indented
28
+ Then nothing
29
+ """
30
+ When I run `greener`
31
+ Then the output should contain exactly "foo/indentation.feature:5\n Scenario: poorly indented\n ^^^ inconsistent indentation detected\n\n1 file(s) inspected, 1 offense(s) detected\n"
32
+
33
+ Scenario: multiple issues
34
+ Given a file named "foo/multiple_issues.feature" with:
35
+ """
36
+ Feature: multiple issues
37
+
38
+ Scenario: correctly indented
39
+
40
+ Scenario: poorly indented
41
+ Then nothing
42
+ """
43
+ When I run `greener`
44
+ Then the output should contain "1 file(s) inspected, 2 offense(s) detected\n"
@@ -0,0 +1,7 @@
1
+ require "simplecov"
2
+ require "aruba/cucumber"
3
+ require "aruba/in_process"
4
+ require "greener/runner"
5
+
6
+ Aruba::InProcess.main_class = Greener::Runner
7
+ Aruba.process = Aruba::InProcess
data/greener.gemspec ADDED
@@ -0,0 +1,46 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "greener/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "greener"
8
+ spec.version = Greener::VERSION
9
+ spec.authors = ["smoll"]
10
+ spec.email = ["smollah@theorchard.com"]
11
+
12
+ spec.summary = "A Gherkin .feature file linter"
13
+ spec.description = "Keep your Gherkin readable with the greener linter..."
14
+ spec.homepage = "https://github.com/smoll/greener"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files`.split($RS).reject do |file|
18
+ file =~ %r{^(?:
19
+ spec/.*
20
+ |\.gitignore
21
+ |\.rspec
22
+ |\.rubocop.yml
23
+ |\.rubocop_todo.yml
24
+ |\.simplecov
25
+ |circle.yml
26
+ |cucumber.yml
27
+ |Gemfile
28
+ |Rakefile
29
+ )$}x
30
+ end
31
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
32
+ spec.require_paths = ["lib"]
33
+
34
+ spec.add_dependency "thor", "~> 0.19.1"
35
+ # TODO: rip this out when gherkin3 has a release
36
+ spec.add_dependency "gherkin3-pre-alpha", "~> 3.0.0.alpha.1"
37
+
38
+ spec.add_development_dependency "aruba", "~> 0.6.2"
39
+ spec.add_development_dependency "bundler", ">= 1.9.5"
40
+ spec.add_development_dependency "codeclimate-test-reporter", "~> 0.4.6"
41
+ spec.add_development_dependency "coveralls", "~> 0.7.9"
42
+ spec.add_development_dependency "rake", "~> 10.0"
43
+ spec.add_development_dependency "rspec", "~> 3.3.0"
44
+ spec.add_development_dependency "rubocop", "~> 0.32.0"
45
+ spec.add_development_dependency "simplecov", "~> 0.9.1"
46
+ end
@@ -0,0 +1,51 @@
1
+ module Greener
2
+ module Checker
3
+ # Base checker class
4
+ class Base
5
+ attr_reader :violations
6
+
7
+ def initialize(ast, path, config)
8
+ @ast = ast
9
+ @path = path
10
+ @config = config
11
+
12
+ @violations = []
13
+ end
14
+
15
+ # Method invoked when a checker is applied to a file
16
+ def run
17
+ end
18
+
19
+ # Read the violation message text set in the checker subclass
20
+ def message
21
+ self.class::MSG
22
+ end
23
+
24
+ # Adds violation data to the @violations array
25
+ def log_violation(line, col, raw_txt = nil, msg = nil)
26
+ # Set defaults for last 2 params if not overridden
27
+ raw_txt ||= raw_line(line)
28
+ msg ||= message
29
+
30
+ violation = {}
31
+ violation[:file] = @path
32
+ violation[:line] = line
33
+ violation[:column] = col
34
+ violation[:text_of_line] = raw_txt
35
+ violation[:message] = msg
36
+
37
+ @violations << violation
38
+ end
39
+
40
+ # For readability in checker subclasses
41
+ def feature
42
+ @ast
43
+ end
44
+
45
+ # Given a num, returns the full text corresponding to that line number in the file
46
+ def raw_line(num)
47
+ open(@path).each_line.take(num).last
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,25 @@
1
+ require "greener/checker/base"
2
+
3
+ module Greener
4
+ module Checker
5
+ module Style
6
+ # Ensure .feature filename matches feature name in the Gherkin
7
+ # e.g. filename_of_feature.feature => "Feature: filename of feature"
8
+ # TODO: add config option for toggling flexible capitalization
9
+ class FeatureName < Base
10
+ MSG = "feature title does not match file name"
11
+
12
+ # Returns nil if no violation, or if there is one:
13
+ # { line: 1, column: 1, text_of_line: "Feature: thing", message: "feature title does not match file name" }
14
+ def run
15
+ return unless @config["Enabled"]
16
+
17
+ filename_without_extension = File.basename(@path, ".*")
18
+ return if feature[:name].downcase.gsub(" ", "_") == filename_without_extension
19
+
20
+ log_violation(feature[:location][:line], feature[:location][:column])
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,44 @@
1
+ require "greener/checker/base"
2
+
3
+ module Greener
4
+ module Checker
5
+ module Style
6
+ # Ensure keywords are indented correctly
7
+ # Ref: https://github.com/bbatsov/rubocop/commit/44c1cdd5d9bc1c3588ea7841fc6e9543126306e8
8
+ class IndentationWidth < Base
9
+ MSG = "inconsistent indentation detected"
10
+
11
+ def run
12
+ return unless @config["Enabled"]
13
+
14
+ check_feature_line
15
+ check_every_scenario
16
+ end
17
+
18
+ def check_feature_line
19
+ return if feature[:location][:column] == 1
20
+ log_violation(feature[:location][:line], feature[:location][:column])
21
+ end
22
+
23
+ def check_every_scenario
24
+ feature[:scenarioDefinitions].each do |scenario|
25
+ scenario[:steps].each { |step| check_a_step(step) }
26
+
27
+ next if scenario[:location][:column] == (1 + configured_indentation_width)
28
+ log_violation(scenario[:location][:line], scenario[:location][:column])
29
+ end
30
+ end
31
+
32
+ def check_a_step(step) # nil if a scenario has no steps, or
33
+ # {:type=>:Step, :location=>{:line=>6, :column=>5}, :keyword=>"Then ", :text=>"nothing"}
34
+ return if step[:location][:column] == (1 + configured_indentation_width * 2)
35
+ log_violation(step[:location][:line], step[:location][:column])
36
+ end
37
+
38
+ def configured_indentation_width
39
+ @config["Width"]
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,20 @@
1
+ require "thor"
2
+
3
+ require "greener/linter"
4
+
5
+ module Greener
6
+ # Main Thor application
7
+ # Subcommands map directly to instance methods in this class.
8
+ # e.g. entering `greener whatever` in your terminal should invoke the App#whatever method
9
+ class CLI < Thor
10
+ desc "lint", "The default task to run when no command is given"
11
+ method_options %w( config -c ) => :string
12
+ def lint
13
+ linter = Linter.new(options[:config])
14
+ linter.lint
15
+ linter.print_results
16
+ end
17
+
18
+ default_task :lint
19
+ end
20
+ end
@@ -0,0 +1,94 @@
1
+ require "yaml"
2
+
3
+ require "greener/utils"
4
+ require "greener/custom_error"
5
+
6
+ # Require all checker files here
7
+ require "greener/checker/style/feature_name"
8
+ require "greener/checker/style/indentation_width"
9
+
10
+ module Greener
11
+ # Read configs from a user-specified greener.yml or fallback to defaults
12
+ class ConfigStore
13
+ include Utils
14
+
15
+ attr_reader :checkers, :files
16
+
17
+ def initialize(path, default_path = nil)
18
+ @path = path
19
+ default_path ||= default_absolute_path
20
+ @default_path = default_path
21
+
22
+ @checkers = {}
23
+ @files = []
24
+ end
25
+
26
+ def resolve
27
+ if @path
28
+ fail CustomError, "No config file found at specified path: #{@path}" unless File.exist? @path
29
+ config = load_yml_file @path
30
+ end
31
+ defaults = load_yml_file @default_path
32
+
33
+ @all = @path ? defaults.merge(config) : defaults
34
+
35
+ validate
36
+ self
37
+ end
38
+
39
+ # Stub-able methods
40
+ def load_yml_file(path)
41
+ YAML.load_file(path)
42
+ end
43
+
44
+ def files_matching_glob(glob)
45
+ Dir.glob(glob).select { |e| File.file? e }
46
+ end
47
+
48
+ private
49
+
50
+ def validate
51
+ set_checkers
52
+ set_files
53
+
54
+ @all.each do |k, _v|
55
+ fail CustomError, "Unknown option in config file: #{k}" # TODO: print warning instead of fail
56
+ end
57
+ end
58
+
59
+ def set_checkers
60
+ @all.each do |k, v|
61
+ next unless %w( Style/ Lint/ ).any? { |prefix| k.start_with?(prefix) }
62
+ checker_klass = checker_from_string(k)
63
+ @checkers[checker_klass] = v
64
+ @all.delete(k)
65
+ end
66
+ end
67
+
68
+ def set_files
69
+ if @all["FileList"].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 == "FileList"
76
+ discover_files(v)
77
+ @all.delete(k)
78
+ end
79
+ end
80
+
81
+ def discover_files(hash)
82
+ includes = []
83
+ excludes = []
84
+
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
88
+ end
89
+
90
+ def default_absolute_path
91
+ File.expand_path("../../../config/defaults.yml", __FILE__)
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,3 @@
1
+ module Greener
2
+ class CustomError < StandardError; end
3
+ end
@@ -0,0 +1,53 @@
1
+ require "gherkin3/parser"
2
+ require "gherkin3/token_scanner"
3
+ require "gherkin3/ast_builder"
4
+ require "gherkin3/token_matcher"
5
+
6
+ require "greener/config_store"
7
+
8
+ module Greener
9
+ # Parse then lint a collection of .feature files for violations
10
+ class Linter
11
+ def initialize(config_path)
12
+ @config = ConfigStore.new(config_path).resolve
13
+ @results = []
14
+ end
15
+
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
+ 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 ""
31
+ end
32
+
33
+ conclusion = @results.empty? ? "no offenses detected" : "#{@results.count} offense(s) detected"
34
+
35
+ puts "#{@config.files.count} file(s) inspected, #{conclusion}"
36
+ end
37
+
38
+ private
39
+
40
+ def parse_single_file(fname)
41
+ parser = Gherkin3::Parser.new
42
+ scanner = Gherkin3::TokenScanner.new(fname)
43
+ builder = Gherkin3::AstBuilder.new
44
+ ast = parser.parse(scanner, builder, Gherkin3::TokenMatcher.new)
45
+
46
+ @config.checkers.each do |sc_klass, sc_opts|
47
+ checker = sc_klass.new(ast, fname, sc_opts)
48
+ checker.run
49
+ @results += checker.violations
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,63 @@
1
+ require "greener/cli"
2
+
3
+ begin # require any dev dependencies here
4
+ require "byebug"
5
+ rescue LoadError # rubocop:disable Lint/HandleExceptions
6
+ end
7
+
8
+ module Greener
9
+ # Aruba In Process + Thor integration
10
+ # Based on https://github.com/erikhuda/thor/wiki/Integrating-with-Aruba-In-Process-Runs
11
+ class Runner
12
+ # Allow everything fun to be injected from the outside while defaulting to normal implementations.
13
+ def initialize(argv, stdin = STDIN, stdout = STDOUT, stderr = STDERR, kernel = Kernel)
14
+ @argv = argv
15
+ @stdin = stdin
16
+ @stdout = stdout
17
+ @stderr = stderr
18
+ @kernel = kernel
19
+ end
20
+
21
+ def execute!
22
+ exit_code = begin
23
+ # Thor accesses these streams directly rather than letting them be injected, so we replace them...
24
+ $stderr = @stderr
25
+ $stdin = @stdin
26
+ $stdout = @stdout
27
+
28
+ # Run our normal Thor app the way we know and love.
29
+ Greener::CLI.start(@argv)
30
+
31
+ # Thor::Base#start does not have a return value, assume success if no exception is raised.
32
+ 0
33
+ rescue Greener::CustomError => e
34
+ @stderr.puts e.message
35
+ 1
36
+ rescue StandardError => e
37
+ # The ruby interpreter would pipe this to STDERR and exit 1 in the case of an unhandled exception
38
+ b = e.backtrace
39
+ @stderr.puts("#{b.shift}: #{e.message} (#{e.class})")
40
+ @stderr.puts(b.map { |s| "\tfrom #{s}" }.join("\n"))
41
+ 1
42
+ rescue SystemExit => e
43
+ e.status
44
+ ensure
45
+ # TODO: reset your app here, free up resources, etc.
46
+ # Examples:
47
+ # MyApp.logger.flush
48
+ # MyApp.logger.close
49
+ # MyApp.logger = nil
50
+ #
51
+ # MyApp.reset_singleton_instance_variables
52
+
53
+ # ...then we put the streams back.
54
+ $stderr = STDERR
55
+ $stdin = STDIN
56
+ $stdout = STDOUT
57
+ end
58
+
59
+ # Proxy our exit code back to the injected kernel.
60
+ @kernel.exit(exit_code)
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,25 @@
1
+ module Greener
2
+ # Useful shared utils
3
+ module Utils
4
+ def checker_from_string(str)
5
+ namespaced = str.gsub("/", "::")
6
+ constantize "Greener::Checker::#{namespaced}"
7
+ rescue NameError
8
+ raise CustomError, "Unknown checker specified: #{str}" # TODO: print warning instead of failing
9
+ end
10
+
11
+ private
12
+
13
+ # Borrowed from Rails
14
+ def constantize(camel_cased_word)
15
+ names = camel_cased_word.split("::")
16
+ names.shift if names.empty? || names.first.empty?
17
+
18
+ constant = Object
19
+ names.each do |name|
20
+ constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
21
+ end
22
+ constant
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,4 @@
1
+ # Gem version
2
+ module Greener
3
+ VERSION = "0.0.1.1"
4
+ end
data/lib/greener.rb ADDED
@@ -0,0 +1 @@
1
+ require "greener/runner"
metadata ADDED
@@ -0,0 +1,205 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: greener
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - smoll
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.19.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.19.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: gherkin3-pre-alpha
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 3.0.0.alpha.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 3.0.0.alpha.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: aruba
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.6.2
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.6.2
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 1.9.5
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 1.9.5
69
+ - !ruby/object:Gem::Dependency
70
+ name: codeclimate-test-reporter
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.4.6
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.4.6
83
+ - !ruby/object:Gem::Dependency
84
+ name: coveralls
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.7.9
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.7.9
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '10.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '10.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 3.3.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 3.3.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: rubocop
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 0.32.0
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 0.32.0
139
+ - !ruby/object:Gem::Dependency
140
+ name: simplecov
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 0.9.1
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 0.9.1
153
+ description: Keep your Gherkin readable with the greener linter...
154
+ email:
155
+ - smollah@theorchard.com
156
+ executables:
157
+ - greener
158
+ extensions: []
159
+ extra_rdoc_files: []
160
+ files:
161
+ - LICENSE.txt
162
+ - README.md
163
+ - bin/greener
164
+ - config/defaults.yml
165
+ - config/dogfood.yml
166
+ - features/configuration.feature
167
+ - features/lint.feature
168
+ - features/support/env.rb
169
+ - greener.gemspec
170
+ - lib/greener.rb
171
+ - lib/greener/checker/base.rb
172
+ - lib/greener/checker/style/feature_name.rb
173
+ - lib/greener/checker/style/indentation_width.rb
174
+ - lib/greener/cli.rb
175
+ - lib/greener/config_store.rb
176
+ - lib/greener/custom_error.rb
177
+ - lib/greener/linter.rb
178
+ - lib/greener/runner.rb
179
+ - lib/greener/utils.rb
180
+ - lib/greener/version.rb
181
+ homepage: https://github.com/smoll/greener
182
+ licenses:
183
+ - MIT
184
+ metadata: {}
185
+ post_install_message:
186
+ rdoc_options: []
187
+ require_paths:
188
+ - lib
189
+ required_ruby_version: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - ">="
192
+ - !ruby/object:Gem::Version
193
+ version: '0'
194
+ required_rubygems_version: !ruby/object:Gem::Requirement
195
+ requirements:
196
+ - - ">="
197
+ - !ruby/object:Gem::Version
198
+ version: '0'
199
+ requirements: []
200
+ rubyforge_project:
201
+ rubygems_version: 2.2.2
202
+ signing_key:
203
+ specification_version: 4
204
+ summary: A Gherkin .feature file linter
205
+ test_files: []