diff --git a/exe/sass b/exe/sass index ca4c0c28..afba0b84 100755 --- a/exe/sass +++ b/exe/sass @@ -6,15 +6,7 @@ require_relative '../ext/sass/cli' module Sass # The `sass` command line interface module CLI - begin - Kernel.exec(*COMMAND, *ARGV) - rescue Errno::ENOENT - require_relative '../lib/sass/elf' - - raise if ELF::INTERPRETER.nil? - - Kernel.exec(ELF::INTERPRETER, *COMMAND, *ARGV) - end + Kernel.exec(*COMMAND, *ARGV) end private_constant :CLI diff --git a/ext/sass/Rakefile b/ext/sass/Rakefile index 97ee6de7..0f6a65d7 100644 --- a/ext/sass/Rakefile +++ b/ext/sass/Rakefile @@ -30,6 +30,8 @@ rescue StandardError end file 'cli.rb' => %w[dart-sass] do |t| + require_relative '../../lib/sass/elf' + exe = 'dart-sass/sass' exe = "#{exe}#{['', '.bat', '.exe'].find { |ext| File.exist?("#{exe}#{ext}") }}" @@ -40,27 +42,58 @@ file 'cli.rb' => %w[dart-sass] do |t| snapshot = 'dart-sass/src/sass.snapshot' command = if File.exist?(runtime) && File.exist?(snapshot) - " - File.absolute_path('#{runtime}', __dir__).freeze, - File.absolute_path('#{snapshot}', __dir__).freeze - " + [runtime, snapshot] else - " - File.absolute_path('#{exe}', __dir__).freeze - " + [exe] end - File.write(t.name, <<~CLI_RB) - # frozen_string_literal: true + interpreter = File.open(command[0], 'rb') do |file| + Sass.const_get(:ELF).new(file).interpreter + rescue ArgumentError + nil + end - module Sass - module CLI - COMMAND = [#{command}].freeze - end + command_source = command.map do |argument| + "File.absolute_path('#{argument}', __dir__).freeze" + end.join(', + ') - private_constant :CLI - end - CLI_RB + if interpreter.nil? + File.write(t.name, <<~CLI_RB) + # frozen_string_literal: true + + module Sass + module CLI + COMMAND = [ + #{command_source} + ].freeze + end + + private_constant :CLI + end + CLI_RB + else + File.write(t.name, <<~CLI_RB) + # frozen_string_literal: true + + require_relative '../../lib/sass/elf' + + module Sass + module CLI + INTERPRETER = '#{interpreter}' + + COMMAND = [ + *(ELF::INTERPRETER unless ELF::INTERPRETER.nil? || + ELF::INTERPRETER == INTERPRETER || + !ELF::INTERPRETER.end_with?(INTERPRETER)), + #{command_source} + ].freeze + end + + private_constant :CLI + end + CLI_RB + end end file 'embedded_sass.proto' => %w[cli.rb] do |t| diff --git a/lib/sass/compiler/connection.rb b/lib/sass/compiler/connection.rb index d59f46db..d5631034 100644 --- a/lib/sass/compiler/connection.rb +++ b/lib/sass/compiler/connection.rb @@ -12,15 +12,7 @@ class Compiler class Connection def initialize @mutex = Mutex.new - @stdin, @stdout, @stderr, @wait_thread = begin - Open3.popen3(*CLI::COMMAND, '--embedded', chdir: __dir__) - rescue Errno::ENOENT - require_relative '../elf' - - raise if ELF::INTERPRETER.nil? - - Open3.popen3(ELF::INTERPRETER, *CLI::COMMAND, '--embedded', chdir: __dir__) - end + @stdin, @stdout, @stderr, @wait_thread = Open3.popen3(*CLI::COMMAND, '--embedded', chdir: __dir__) @stdin.binmode diff --git a/lib/sass/elf.rb b/lib/sass/elf.rb index 01587881..775deb41 100644 --- a/lib/sass/elf.rb +++ b/lib/sass/elf.rb @@ -147,7 +147,7 @@ def initialize(buffer) elf_ehdr = :Elf64_Ehdr elf_phdr = :Elf64_Phdr else - raise ArgumentError + raise EncodingError end case @ehdr[:e_ident][EI_DATA] @@ -156,7 +156,7 @@ def initialize(buffer) when ELFDATA2MSB little_endian = false else - raise ArgumentError + raise EncodingError end @ehdr.merge!(read(elf_ehdr, little_endian)) @@ -189,7 +189,7 @@ def interpreter @buffer.seek(phdr[:p_offset], IO::SEEK_SET) interpreter = @buffer.read(phdr[:p_filesz]) - raise ArgumentError unless interpreter.end_with?("\0") + raise EncodingError unless interpreter.end_with?("\0") interpreter.chomp!("\0") end @@ -215,7 +215,7 @@ def read(type, little_endian) end end end - end + end.freeze end private_constant :ELF