Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable Windows support #319

Merged
merged 4 commits into from
Oct 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: ci

on:
pull_request:
branches:
- master
push:
branches:
- master

jobs:
test:
strategy:
matrix:
os: [ubuntu, macos, windows]
ruby: [2.5]
runs-on: ${{ matrix.os }}-latest
steps:
- uses: actions/checkout@v2
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
- run: bundle install
- run: bundle exec rake
14 changes: 14 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,17 @@ If you're stuck, ask questions!
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request

## Running Tests on Windows

### Setup

1. Ensure you've installed Ruby and the MSYS2 devkit and have ran `ridk enable` in your shell. The `ridk enable` command adds make to the path so the compile rake task works.

1. Open your shell as Administrator (`Run as Administrator`), as the tests create and delete symlinks

### Running Tests

> ridk enable
> bundle install
> bundle exec rake
8 changes: 6 additions & 2 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ Rake::ExtensionTask.new do |ext|
ext.gem_spec = gemspec
end

task :test do
sh 'bin/testunit'
require "rake/testtask"

Rake::TestTask.new(:test) do |t|
t.libs << "test"
t.libs << "lib"
t.test_files = FileList["test/**/*_test.rb"]
end

task(default: %i(compile test))
4 changes: 2 additions & 2 deletions lib/bootsnap/compile_cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ def self.permission_error(path)
end

def self.supported?
# only enable on 'ruby' (MRI), POSIX (darwin, linux, *bsd), and >= 2.3.0
# only enable on 'ruby' (MRI), POSIX (darwin, linux, *bsd), Windows (RubyInstaller2) and >= 2.3.0
RUBY_ENGINE == 'ruby' &&
RUBY_PLATFORM =~ /darwin|linux|bsd/ &&
RUBY_PLATFORM =~ /darwin|linux|bsd|mswin|mingw|cygwin/ &&
Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.3.0")
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/bootsnap/load_path_cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def setup(cache_path:, development_mode:, active_support: true)

def supported?
RUBY_ENGINE == 'ruby' &&
RUBY_PLATFORM =~ /darwin|linux|bsd/
RUBY_PLATFORM =~ /darwin|linux|bsd|mswin|mingw|cygwin/
end
end
end
Expand Down
22 changes: 16 additions & 6 deletions test/compile_cache_key_format_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,22 @@ def test_key_mtime
end

def test_fetch
actual = Bootsnap::CompileCache::Native.fetch(@tmp_dir, '/dev/null', TestHandler, nil)
assert_equal('NEATO /DEV/NULL', actual)
data = File.read("#{@tmp_dir}/8c/d2d180bbd995df")
assert_equal("neato /dev/null", data.force_encoding(Encoding::BINARY)[64..-1])
actual = Bootsnap::CompileCache::Native.fetch(@tmp_dir, '/dev/null', TestHandler, nil)
assert_equal('NEATO /DEV/NULL', actual)
if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
target = 'NUL'
expected_file = "#{@tmp_dir}/36/9eba19c29ffe00"
else
target = '/dev/null'
expected_file = "#{@tmp_dir}/8c/d2d180bbd995df"
end

actual = Bootsnap::CompileCache::Native.fetch(@tmp_dir, target, TestHandler, nil)
assert_equal("NEATO #{target.upcase}", actual)

data = File.read(expected_file)
assert_equal("neato #{target}", data.force_encoding(Encoding::BINARY)[64..-1])

actual = Bootsnap::CompileCache::Native.fetch(@tmp_dir, target, TestHandler, nil)
assert_equal("NEATO #{target.upcase}", actual)
end

def test_unexistent_fetch
Expand Down
23 changes: 18 additions & 5 deletions test/compile_cache_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,24 @@ def test_coverage_running?
end

def test_no_write_permission_to_cache
path = Help.set_file('a.rb', 'a = 3', 100)
folder = File.dirname(Help.cache_path(@tmp_dir, path))
FileUtils.mkdir_p(folder)
FileUtils.chmod(0400, folder)
assert_raises(Bootsnap::CompileCache::PermissionError) { load(path) }
if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
# Always pass this test on Windows because directories aren't read, only
# listed. You can restrict the ability to list directory contents on
# Windows or you can set ACLS on a folder such that it is not allowed to
# list contents.
#
# Since we can't read directories on windows, this specific test doesn't
# make sense. In addtion we test read-only files in
# `test_can_open_read_only_cache` so we are covered testing reading
# read-only files.
pass
else
path = Help.set_file('a.rb', 'a = 3', 100)
folder = File.dirname(Help.cache_path(@tmp_dir, path))
FileUtils.mkdir_p(folder)
FileUtils.chmod(0400, folder)
assert_raises(Bootsnap::CompileCache::PermissionError) { load(path) }
end
end

def test_can_open_read_only_cache
Expand Down
33 changes: 21 additions & 12 deletions test/load_path_cache/path_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@ def setup

def test_stability
require('time')
time_file = Time.method(:rfc2822).source_location[0]
volatile = Path.new(__FILE__)
stable = Path.new(time_file)
unknown = Path.new('/who/knows')
lib = Path.new(RbConfig::CONFIG['libdir'] + '/a')
site = Path.new(RbConfig::CONFIG['sitedir'] + '/b')
bundler = Path.new('/bp/3')
time_file = Time.method(:rfc2822).source_location[0]
volatile = Path.new(__FILE__)
stable = Path.new(time_file)
unknown = Path.new('/who/knows')
lib = Path.new(RbConfig::CONFIG['libdir'] + '/a')
site = Path.new(RbConfig::CONFIG['sitedir'] + '/b')
absolute_prefix = RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/ ? ENV['SystemDrive'] : ''
bundler = Path.new(absolute_prefix + '/bp/3')

Bundler.stubs(:bundle_path).returns('/bp')
Bundler.stubs(:bundle_path).returns(absolute_prefix + '/bp')

assert(stable.stable?, "The stable path #{stable.path.inspect} was unexpectedly not stable.")
refute(stable.volatile?, "The stable path #{stable.path.inspect} was unexpectedly volatile.")
Expand All @@ -34,10 +35,18 @@ def test_stability
end

def test_non_directory?
refute(Path.new('/dev').non_directory?)
refute(Path.new('/nope').non_directory?)
assert(Path.new('/dev/null').non_directory?)
assert(Path.new('/etc/hosts').non_directory?)
if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
refute(Path.new('c:/dev').non_directory?)
refute(Path.new('c:/nope').non_directory?)
# there isn't a direct analog i could think of
# assert(Path.new('/dev/null').non_directory?)
assert(Path.new("#{ENV['WinDir']}/System32/Drivers/Etc/hosts").non_directory?)
else
refute(Path.new('/dev').non_directory?)
refute(Path.new('/nope').non_directory?)
assert(Path.new('/dev/null').non_directory?)
assert(Path.new('/etc/hosts').non_directory?)
end
end

def test_volatile_cache_valid_when_mtime_has_not_changed
Expand Down
4 changes: 2 additions & 2 deletions test/load_path_cache/realpath_cache_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ def setup
@symlinked_dir = "#{@base_dir}/symlink"
FileUtils.ln_s(@absolute_dir, @symlinked_dir)

real_caller = File.new("#{@absolute_dir}/real_caller.rb", 'w').path
real_caller = File.new("#{@absolute_dir}/real_caller.rb", 'w').tap(&:close).path
symlinked_caller = "#{@absolute_dir}/symlinked_caller.rb"

FileUtils.ln_s(real_caller, symlinked_caller)

EXTENSIONS.each do |ext|
real_required = File.new("#{@absolute_dir}/real_required#{ext}", 'w').path
real_required = File.new("#{@absolute_dir}/real_required#{ext}", 'w').tap(&:close).path

symlinked_required = "#{@absolute_dir}/symlinked_required#{ext}"
FileUtils.ln_s(real_required, symlinked_required)
Expand Down