Skip to content

Commit 057c994

Browse files
authored
Merge pull request #319 from jpogran/windows-support
2 parents 737ff88 + 32394ff commit 057c994

9 files changed

Lines changed: 104 additions & 30 deletions

File tree

.github/workflows/ci.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: ci
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- master
7+
push:
8+
branches:
9+
- master
10+
11+
jobs:
12+
test:
13+
strategy:
14+
matrix:
15+
os: [ubuntu, macos, windows]
16+
ruby: [2.5]
17+
runs-on: ${{ matrix.os }}-latest
18+
steps:
19+
- uses: actions/checkout@v2
20+
- uses: ruby/setup-ruby@v1
21+
with:
22+
ruby-version: ${{ matrix.ruby }}
23+
- run: bundle install
24+
- run: bundle exec rake

CONTRIBUTING.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,17 @@ If you're stuck, ask questions!
1919
3. Commit your changes (`git commit -am 'Add some feature'`)
2020
4. Push to the branch (`git push origin my-new-feature`)
2121
5. Create a new Pull Request
22+
23+
## Running Tests on Windows
24+
25+
### Setup
26+
27+
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.
28+
29+
1. Open your shell as Administrator (`Run as Administrator`), as the tests create and delete symlinks
30+
31+
### Running Tests
32+
33+
> ridk enable
34+
> bundle install
35+
> bundle exec rake

Rakefile

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@ Rake::ExtensionTask.new do |ext|
1010
ext.gem_spec = gemspec
1111
end
1212

13-
task :test do
14-
sh 'bin/testunit'
13+
require "rake/testtask"
14+
15+
Rake::TestTask.new(:test) do |t|
16+
t.libs << "test"
17+
t.libs << "lib"
18+
t.test_files = FileList["test/**/*_test.rb"]
1519
end
1620

1721
task(default: %i(compile test))

lib/bootsnap/compile_cache.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ def self.permission_error(path)
3434
end
3535

3636
def self.supported?
37-
# only enable on 'ruby' (MRI), POSIX (darwin, linux, *bsd), and >= 2.3.0
37+
# only enable on 'ruby' (MRI), POSIX (darwin, linux, *bsd), Windows (RubyInstaller2) and >= 2.3.0
3838
RUBY_ENGINE == 'ruby' &&
39-
RUBY_PLATFORM =~ /darwin|linux|bsd/ &&
39+
RUBY_PLATFORM =~ /darwin|linux|bsd|mswin|mingw|cygwin/ &&
4040
Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.3.0")
4141
end
4242
end

lib/bootsnap/load_path_cache.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def setup(cache_path:, development_mode:, active_support: true)
6161

6262
def supported?
6363
RUBY_ENGINE == 'ruby' &&
64-
RUBY_PLATFORM =~ /darwin|linux|bsd/
64+
RUBY_PLATFORM =~ /darwin|linux|bsd|mswin|mingw|cygwin/
6565
end
6666
end
6767
end

test/compile_cache_key_format_test.rb

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,22 @@ def test_key_mtime
5959
end
6060

6161
def test_fetch
62-
actual = Bootsnap::CompileCache::Native.fetch(@tmp_dir, '/dev/null', TestHandler, nil)
63-
assert_equal('NEATO /DEV/NULL', actual)
64-
data = File.read("#{@tmp_dir}/8c/d2d180bbd995df")
65-
assert_equal("neato /dev/null", data.force_encoding(Encoding::BINARY)[64..-1])
66-
actual = Bootsnap::CompileCache::Native.fetch(@tmp_dir, '/dev/null', TestHandler, nil)
67-
assert_equal('NEATO /DEV/NULL', actual)
62+
if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
63+
target = 'NUL'
64+
expected_file = "#{@tmp_dir}/36/9eba19c29ffe00"
65+
else
66+
target = '/dev/null'
67+
expected_file = "#{@tmp_dir}/8c/d2d180bbd995df"
68+
end
69+
70+
actual = Bootsnap::CompileCache::Native.fetch(@tmp_dir, target, TestHandler, nil)
71+
assert_equal("NEATO #{target.upcase}", actual)
72+
73+
data = File.read(expected_file)
74+
assert_equal("neato #{target}", data.force_encoding(Encoding::BINARY)[64..-1])
75+
76+
actual = Bootsnap::CompileCache::Native.fetch(@tmp_dir, target, TestHandler, nil)
77+
assert_equal("NEATO #{target.upcase}", actual)
6878
end
6979

7080
def test_unexistent_fetch

test/compile_cache_test.rb

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,24 @@ def test_coverage_running?
2424
end
2525

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

3447
def test_can_open_read_only_cache

test/load_path_cache/path_test.rb

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@ def setup
1111

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

22-
Bundler.stubs(:bundle_path).returns('/bp')
23+
Bundler.stubs(:bundle_path).returns(absolute_prefix + '/bp')
2324

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

3637
def test_non_directory?
37-
refute(Path.new('/dev').non_directory?)
38-
refute(Path.new('/nope').non_directory?)
39-
assert(Path.new('/dev/null').non_directory?)
40-
assert(Path.new('/etc/hosts').non_directory?)
38+
if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
39+
refute(Path.new('c:/dev').non_directory?)
40+
refute(Path.new('c:/nope').non_directory?)
41+
# there isn't a direct analog i could think of
42+
# assert(Path.new('/dev/null').non_directory?)
43+
assert(Path.new("#{ENV['WinDir']}/System32/Drivers/Etc/hosts").non_directory?)
44+
else
45+
refute(Path.new('/dev').non_directory?)
46+
refute(Path.new('/nope').non_directory?)
47+
assert(Path.new('/dev/null').non_directory?)
48+
assert(Path.new('/etc/hosts').non_directory?)
49+
end
4150
end
4251

4352
def test_volatile_cache_valid_when_mtime_has_not_changed

test/load_path_cache/realpath_cache_test.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ def setup
1616
@symlinked_dir = "#{@base_dir}/symlink"
1717
FileUtils.ln_s(@absolute_dir, @symlinked_dir)
1818

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

2222
FileUtils.ln_s(real_caller, symlinked_caller)
2323

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

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

0 commit comments

Comments
 (0)