简体   繁体   中英

Rspec installation error - Invalid argument

I just moved to a new laptop running on Win 10/ruby 2.2.2/Rails 4.2.0 (No problem on previous Win 8 ruby 2.0.0/Rails 4.2/rspec 3.2). Now when installing rspec , there is a strange error below:

$ rails g rspec:install
   identical  .rspec
       exist  spec
      create  spec/C:/Users/Jun C/AppData/Local/Temp/d20160219-10996-1x6hu8w/spec/spec_helper.rb
C:/Ruby22-x64/lib/ruby/2.2.0/fileutils.rb:252:in `mkdir': Invalid argument @ dir_s_mkdir - C:/D/code/rails_proj/engines/simple_orderx/spec/C: (Errno::EINVAL)
        from C:/Ruby22-x64/lib/ruby/2.2.0/fileutils.rb:252:in `fu_mkdir'
        from C:/Ruby22-x64/lib/ruby/2.2.0/fileutils.rb:226:in `block (2 levels) in mkdir_p'
        from C:/Ruby22-x64/lib/ruby/2.2.0/fileutils.rb:224:in `reverse_each'
        from C:/Ruby22-x64/lib/ruby/2.2.0/fileutils.rb:224:in `block in mkdir_p'
        from C:/Ruby22-x64/lib/ruby/2.2.0/fileutils.rb:210:in `each'
        from C:/Ruby22-x64/lib/ruby/2.2.0/fileutils.rb:210:in `mkdir_p'
        from C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/thor-0.19.1/lib/thor/actions/create_file.rb:61:in `block in invoke!'
        from C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/thor-0.19.1/lib/thor/actions/empty_directory.rb:116:in `call'
        from C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/thor-0.19.1/lib/thor/actions/empty_directory.rb:116:in `invoke_with_conflict_check'
        from C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/thor-0.19.1/lib/thor/actions/create_file.rb:60:in `invoke!'

There is /spec under Rails app root. The spec-helper file should be generated under /spec as /spec/spec-helper.rb . However the installation tried to generate spec-helper at spec/C:/Users/Jun C/AppData/Local/Temp/d20160219-10996-1x6hu8w/spec/ . It seems that the path is wrong.

Here is the line in Gemfile :

s.add_development_dependency "rspec-rails", ">= 3.2.0"

Here is the config in engine.rb

   config.generators do |g|
      g.template_engine :erb
      g.integration_tool :rspec
      g.test_framework :rspec
      g.fixture_replacement :factory_girl, :dir => "spec/factories"  
    end  

The rspec version is 3.2.2 . How to fix this wrong path in rspec installation?

My Environment

  • Windows 10
  • ruby 2.4.4p296 (2018-03-28 revision 63013) [x64-mingw32]
  • Rails 5.2.0
  • rspec-rails (3.7.2)
  • thor (0.20.0)

TL;DR

Because Dir.mktmpdir (as used by RSpec-rails) and Dir.glob (as used by Thor) return mismatching user directory paths on Windows 10, Thor cannot generate relative paths correctly, resulting in invalid paths that are causing file operations to fail. This issue is unique to Windows 10. Make sure your RSpec-rails and Thor gems are up-to-date. If that doesn't resolve your issue, see workaround below.

Under The Hood

The rails generate rspec:install command:

  1. creates a temporary directory
  2. populates it with the files it needs
  3. uses Thor to copy those files into your Rails app

RSpec-rails uses Dir.mktmpdir during step one. On Windows 10, the resulting path looks like this:

Dir.mktmpdir() => C:/Users/BEN~1.AMO/AppData/Local/Temp/...

This path is derived from the Windows 10 TMP environment variable:

irb(main):005:0> ENV['TMP']
=> "C:\\Users\\BEN~1.AMO\\AppData\\Local\\Temp"

Thor uses Dir.glob when looking for files to copy during step three. On Windows 10, the paths it finds look like this:

Dir.glob(lookup, File::FNM_DOTMATCH) => C:/Users/ben.amos/AppData/Local/Temp/...

These paths are derived from the HOME environment variable:

irb(main):006:0> ENV['HOME']
=> "C:/Users/ben.amos"

When Thor finds a file to copy with Dir.glob , it first tries to derive a relative path by removing the temp directory part of the path - the one created by Dir.mktmpdir . But since the Dir.glob and Dir.mktmpdir paths don't match, String.gsub does nothing, the absolute path is retained, subsequent filepath operations create an invalid path string, and ... BOOM. The copy fails as the OP describes.

If curious, you can verify this behavior yourself by looking at these two files:

RSpec-rails gem: lib\generators\rspec\install\install_generator.rb
Thor gem: lib\thor\actions\directory.rb

The Workaround

The easiest, least invasive workaround I've been able to produce is to temporarily set ENV['TMP'] to something else. You can do this early in the Rails setup process. Just use some non-user-specific path, like so:

  1. Open config/application.rb .
  2. Add the following to the bottom of your Application class.

    ENV['TMP'] = 'C:/Windows/Temp' # or any other valid temp directory

  3. Run rails generate rspec:install .

  4. Remove the line that was added in step 2.

Once the files you need are in place, you shouldn't have to worry about this again.

The Formal Fix

Either RSpec needs to use a different temp directory for us Windows folk, or Thor needs to use smarter logic for its paths. There's an open ticket on Thor's Github .

Think the most fast solution is use the correct versions, u can use:

gem 'rails', '4.2.3'
gem 'sqlite3'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.1.0'
gem 'therubyracer', platforms: :ruby
gem 'jquery-rails'
gem 'turbolinks'
gem 'jbuilder', '~> 2.0'
gem 'sdoc', '~> 0.4.0', group: :doc

gem 'web-console', '~> 2.0', group: :development

group :development, :test do
  gem 'byebug'
  gem 'spring'
end

group :test do
 gem 'rspec-rails', '~> 3.0'
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

gem 'capybara', '~> 2.4.4'
gem 'poltergeist', '~> 1.6.0'
gem 'phantomjs', '~> 1.9.8.0'
gem 'bootstrap-sass'
gem 'minitest'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM