cucumber-attic / gherkin

Cross platform parser for the Gherkin language. Used by Cucumber to parse .feature files.
252 stars 126 forks source link

warning: already initialized constant Gherkin::TokenMatcher::LANGUAGE_PATTERN #207

Closed JaniJegoroff closed 7 years ago

JaniJegoroff commented 8 years ago

I updated our test automation suite to use latest cucumber 2.3.3 from cucumber 1.3.19. Everything is working fine locally but I noticed some warnings in the Jenkins CI logs:

/usr/local/Cellar/ruby/2.1.5/lib/ruby/gems/2.1.0/gems/gherkin-3.2.0/lib/gherkin/token_matcher.rb:6: warning: already initialized constant Gherkin::TokenMatcher::LANGUAGE_PATTERN
/usr/local/lib/ruby/gems/2.1.0/gems/gherkin-3.2.0/lib/gherkin/token_matcher.rb:6: warning: previous definition of LANGUAGE_PATTERN was here
/usr/local/lib/ruby/gems/2.1.0/gems/gherkin-3.2.0/lib/gherkin/dialect.rb:4: warning: already initialized constant Gherkin::DIALECT_FILE_PATH
/usr/local/Cellar/ruby/2.1.5/lib/ruby/gems/2.1.0/gems/gherkin-3.2.0/lib/gherkin/dialect.rb:4: warning: previous definition of DIALECT_FILE_PATH was here
/usr/local/lib/ruby/gems/2.1.0/gems/gherkin-3.2.0/lib/gherkin/dialect.rb:5: warning: already initialized constant Gherkin::DIALECTS
/usr/local/Cellar/ruby/2.1.5/lib/ruby/gems/2.1.0/gems/gherkin-3.2.0/lib/gherkin/dialect.rb:5: warning: previous definition of DIALECTS was here

Gemfile:

gem 'cucumber', '~> 2.3'

Gemfile.lock

cucumber (2.3.3)
builder (>= 2.1.2)
cucumber-core (~> 1.4.0)
cucumber-wire (~> 0.0.1)
diff-lcs (>= 1.1.3)
gherkin (~> 3.2.0)
multi_json (>= 1.7.5, < 2.0)
multi_test (>= 0.1.2)
cucumber-core (1.4.0)
gherkin (~> 3.2.0)
cucumber-wire (0.0.1)
charlierudolph commented 8 years ago

Based on the paths it looks like you are loading gherkin from two different places. Don't know what process is doing that but removing one should help resolve the error.

/usr/local/Cellar/ruby/2.1.5/lib/ruby/gems/2.1.0/gems/gherkin-3.2.0
/usr/local/lib/ruby/gems/2.1.0/gems/gherkin-3.2.0
jorhett commented 8 years ago

So these errors appear when a gem can be found by multiple paths, one of which is a symlink to the other. It also occurs for systems where gems are reloaded, such as rspec/serverspec testing and rails.

Best practice is to always check for constant already being defined with conditional evaluation ala ||= or unless const_defined?

If you google this phrase you'll find every other gem has fixed this problem. Would deeply appreciate a patch in 3.2.1 as a lot of testing tools are locked '~> 3.2.0'

--- lib/gherkin/dialect.rb_orig 2016-05-11 17:27:04.714712882 +0000
+++ lib/gherkin/dialect.rb  2016-05-11 17:23:01.926324245 +0000
@@ -1,8 +1,8 @@
 require 'json'

 module Gherkin
-  DIALECT_FILE_PATH = File.expand_path("gherkin-languages.json", File.dirname(__FILE__))
-  DIALECTS = JSON.parse File.read(DIALECT_FILE_PATH)
+  DIALECT_FILE_PATH ||= File.expand_path("gherkin-languages.json", File.dirname(__FILE__))
+  DIALECTS ||= JSON.parse File.read(DIALECT_FILE_PATH)

   class Dialect
     def self.for(name)
jorhett commented 8 years ago

@charlierudolph FYI the two paths that @JaniJegoroff had above is the common symlink setup used by Brew on Macs, so this will affect many people

I'm seeing the problem when using bundler due to it's files and Ruby's habit of deferencing symlinks when storing the file load path.