From c39ef832e80671963c24ec30e8e350d0b3506c10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=AA=E3=81=A4=E3=81=8D?= Date: Sat, 26 Oct 2024 10:38:12 -0700 Subject: [PATCH] Support JS version of `sass --embedded` --- ext/sass/.gitignore | 2 ++ ext/sass/Rakefile | 74 ++++++++++++++++++++++++++------------- lib/sass/compiler/host.rb | 2 +- 3 files changed, 53 insertions(+), 25 deletions(-) diff --git a/ext/sass/.gitignore b/ext/sass/.gitignore index 23f2a2c0..a4e59778 100644 --- a/ext/sass/.gitignore +++ b/ext/sass/.gitignore @@ -4,5 +4,7 @@ /dart-sass/ /embedded_sass.proto /embedded_sass_pb.rb +/package-lock.json +/node_modules/ /protoc.exe /ruby/ diff --git a/ext/sass/Rakefile b/ext/sass/Rakefile index 7035a4f0..f2fd2dc0 100644 --- a/ext/sass/Rakefile +++ b/ext/sass/Rakefile @@ -10,14 +10,14 @@ end CLEAN.include %w[protoc.exe ruby *.proto *.tar.gz *.zip] -CLOBBER.include %w[dart-sass cli.rb embedded_sass_pb.rb] +CLOBBER.include %w[dart-sass cli.rb embedded_sass_pb.rb node_modules package-lock.json] file 'protoc.exe' do |t| fetch(ENV.fetch('PROTOC_BIN') { SassConfig.default_protoc }, t.name) chmod 'a+x', t.name end -file 'dart-sass' do |t| +file 'dart-sass/sass' do |t| raise if ENV.key?('DART_SASS') gem_install 'sass-embedded', SassConfig.gem_version, SassConfig.gem_platform do |dir| @@ -29,34 +29,58 @@ rescue StandardError rm archive end +file 'node_modules/sass' do + sh 'npm', 'install' +end + +task 'dart-sass' do + Rake::Task['dart-sass/sass'].invoke +rescue NotImplementedError + Rake::Task['node_modules/sass'].invoke +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}") }}" + begin + exe = 'dart-sass/sass' + exe = "#{exe}#{['', '.bat', '.exe'].find { |ext| File.exist?("#{exe}#{ext}") }}" - raise "#{exe} not found" unless File.exist?(exe) + raise Errno::ENOENT, exe unless File.exist?(exe) - runtime = 'dart-sass/src/dart' - runtime = "#{runtime}#{['', '.exe'].find { |ext| File.exist?("#{runtime}#{ext}") }}" - snapshot = 'dart-sass/src/sass.snapshot' + runtime = 'dart-sass/src/dart' + runtime = "#{runtime}#{['', '.exe'].find { |ext| File.exist?("#{runtime}#{ext}") }}" + snapshot = 'dart-sass/src/sass.snapshot' - command = if File.exist?(runtime) && File.exist?(snapshot) - [runtime, snapshot] - else - [exe] - end + command = if File.exist?(runtime) && File.exist?(snapshot) + [runtime, snapshot] + else + [exe] + end - interpreter = File.open(command[0], 'rb') do |file| - Sass.const_get(:ELF).new(file).interpreter - rescue ArgumentError - nil - end + interpreter = File.open(command[0], 'rb') do |file| + Sass.const_get(:ELF).new(file).interpreter + rescue ArgumentError + nil + end + + command_source = command.map do |argument| + "File.absolute_path('#{argument}', __dir__).freeze" + end.join(', + ') + rescue Errno::ENOENT + package = 'node_modules/sass' + + script = File.join(package, SassConfig.package_json(package)['bin']['sass']) - command_source = command.map do |argument| - "File.absolute_path('#{argument}', __dir__).freeze" - end.join(', + interpreter = nil + + command_source = [ + "'node'", + "File.absolute_path('#{script}', __dir__).freeze" + ].join(', ') + end if interpreter.nil? File.write(t.name, <<~CLI_RB) @@ -290,12 +314,14 @@ module SassConfig module_function - def dart_sass_version + def package_json(path = '.') require 'json' - spec = JSON.parse(File.read(File.absolute_path('package.json', __dir__))) + JSON.parse(File.read(File.absolute_path('package.json', path))) + end - spec['dependencies']['sass'] + def dart_sass_version + package_json['dependencies']['sass'] end def default_dart_sass diff --git a/lib/sass/compiler/host.rb b/lib/sass/compiler/host.rb index b1506c0b..1677f466 100644 --- a/lib/sass/compiler/host.rb +++ b/lib/sass/compiler/host.rb @@ -116,7 +116,7 @@ def version_request case version_response.implementation_name when 'dart-sass' - info << '[Dart]' + info << (CLI::COMMAND.first == 'node' ? '[JavaScript]' : '[Dart]') end info