sass-embedded 0.1.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 604bb4648958324aedb4a486c281994eb04bc6a2e685e946c07e62ca83ded8ed
4
- data.tar.gz: 14730abcf938ee7fe9410a1f0055292c6abf95c95a1a7ab2c6f0d7dc3f2893c8
3
+ metadata.gz: 5dc860ffde1f3fb6315c2a43972b245841e10e0b0b4a8979a5a4c7528063cd95
4
+ data.tar.gz: aa76a73fdc4a252b1cd948b90452fa772282408289e99a4e0206c968a5e68898
5
5
  SHA512:
6
- metadata.gz: 629f7ec2916c32f7821153b47c4c6ebeba09d3995d89273113e9b2ebdb0d477eca9f4ae027fd5144e4b6bdc52c83d2eedc9ca8edcac3d1ea6b79f5f86d528f04
7
- data.tar.gz: 2b89c4871759f23a1c3e69d53ca61b1a8e45804435e0d84800beec43aa2bc860c707e3a5d10910e855cbf9d3fece3de658c97739b491b26a1c6aba43dec94fa9
6
+ metadata.gz: b03c95f66214d6e095fd1e11bbeebe24d56443cf90107661007aef30006502296799c07e4c73974cfa0ca7debc7a807a120c86eb99441363af10f699a9cd0148
7
+ data.tar.gz: b834e3e9e2a0eb7acdea42e04c1627edc86f2e146c0b96e79331c646b387f8df861fa59d0efeb46d9f3d176b388804d67b63515cc406efb8bb5d7a3c1d4391f6
@@ -27,16 +27,13 @@ jobs:
27
27
  bundler-cache: true
28
28
 
29
29
  - name: Download dart-sass-embedded
30
- run: bundle exec rake download
30
+ run: bundle exec rake extconf
31
31
  env:
32
32
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33
33
 
34
34
  - name: Test
35
35
  run: bundle exec rake
36
36
 
37
- - name: Build Gem
38
- run: rake build
39
-
40
37
  - name: Install Gem
41
38
  run: rake install
42
39
  env:
data/Gemfile CHANGED
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
  gemspec
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Embedded Sass Host for Ruby
2
2
 
3
+ [![build](https://github.com/ntkme/embedded-host-ruby/actions/workflows/build.yml/badge.svg)](https://github.com/ntkme/embedded-host-ruby/actions/workflows/build.yml)
4
+
3
5
  This is a Ruby library that implements the host side of the [Embedded Sass protocol](https://github.com/sass/sass-embedded-protocol).
4
6
 
5
7
  It exposes a Ruby API for Sass that's backed by a native [Dart Sass](https://sass-lang.com/dart-sass) executable.
data/Rakefile CHANGED
@@ -1,14 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
 
3
5
  task default: :test
4
6
 
5
7
  desc 'Download dart-sass-embedded'
6
- task :download do
8
+ task :extconf do
9
+ system('make', '-C', 'ext/sass_embedded', 'distclean')
7
10
  require_relative 'ext/sass_embedded/extconf'
11
+ system('make', '-C', 'ext/sass_embedded', 'install')
8
12
  end
9
13
 
10
14
  desc 'Run all tests'
11
15
  task :test do
12
16
  $LOAD_PATH.unshift('lib', 'test')
13
- Dir.glob('./test/**/*_test.rb') { |f| require f }
17
+ Dir.glob('./test/**/*_test.rb').sort.each { |f| require f }
14
18
  end
@@ -1,8 +1,17 @@
1
+ ifeq ($(OS),Windows_NT)
2
+ RM = cmd /c del /f /q /s
3
+ else
4
+ RM = rm -fr
5
+ endif
6
+
7
+ .PHONY: all
8
+ all:
9
+
1
10
  .PHONY: install
2
11
  install:
3
12
  ifeq ($(OS),Windows_NT)
4
- powershell -command "Get-Item sass_embedded-*.zip | Expand-Archive -DestinationPath (Get-Location) -Force"
5
- powershell -command "Get-Item protoc-*.zip | Expand-Archive -DestinationPath protoc -Force"
13
+ powershell -Command "Get-Item sass_embedded-*.zip | Expand-Archive -DestinationPath . -Force"
14
+ powershell -Command "Get-Item protoc-*.zip | Expand-Archive -DestinationPath protoc -Force"
6
15
  ./protoc/bin/protoc --ruby_out=. embedded_sass.proto
7
16
  else
8
17
  tar -vxzf sass_embedded-*.tar.gz
@@ -12,24 +21,8 @@ endif
12
21
 
13
22
  .PHONY: clean
14
23
  clean:
15
- ifeq ($(OS),Windows_NT)
16
- powershell -command "Remove-Item sass_embedded -Recurse -Force -ErrorAction Ignore"
17
- powershell -command "Remove-Item protoc -Recurse -Force -ErrorAction Ignore"
18
- powershell -command "Remove-Item embedded_sass_pb.rb -Recurse -Force -ErrorAction Ignore"
19
- else
20
- rm -rf sass_embedded
21
- rm -rf protoc
22
- rm -rf embedded_sass_pb.rb
23
- endif
24
+ $(RM) embedded_sass_pb.rb protoc sass_embedded
24
25
 
25
26
  .PHONY: distclean
26
27
  distclean: clean
27
- ifeq ($(OS),Windows_NT)
28
- powershell -command "Remove-Item sass_embedded-*.zip -Force -ErrorAction Ignore"
29
- powershell -command "Remove-Item protoc-*.zip -Force -ErrorAction Ignore"
30
- powershell -command "Remove-Item embedded_sass.proto -Force -ErrorAction Ignore"
31
- else
32
- rm -rf sass_embedded-*.tar.gz
33
- rm -rf protoc-*.zip
34
- rm -rf embedded_sass.proto
35
- endif
28
+ $(RM) embedded_sass.proto protoc-*.zip sass_embedded-*.tar.gz
@@ -1,131 +1,129 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "mkmf"
4
- require "json"
5
- require "open-uri"
6
- require_relative "../../lib/sass/platform"
4
+ require 'json'
5
+ require 'open-uri'
6
+ require_relative '../../lib/sass/platform'
7
7
 
8
- def api url
9
- headers = {}
10
- headers["Authorization"] = "token #{ENV["GITHUB_TOKEN"]}" if ENV["GITHUB_TOKEN"]
11
- URI.open(url, headers) do |file|
12
- JSON.parse file.read
13
- end
14
- end
8
+ module Sass
9
+ class Extconf
15
10
 
16
- def download url
17
- URI.open(url) do |source|
18
- File.open(File.absolute_path(File.basename(url), __dir__), "wb") do |destination|
19
- destination.write source.read
11
+ def initialize
12
+ download_sass_embedded
13
+ download_protoc
14
+ download_embedded_sass_proto
20
15
  end
21
- end
22
- end
23
16
 
24
- def download_sass_embedded
25
- repo = "sass/dart-sass-embedded"
26
-
27
- release = api("https://api.github.com/repos/#{repo}/releases")[0]['tag_name']
28
-
29
- os = case Sass::Platform::OS
30
- when "darwin"
31
- "macos"
32
- when "linux"
33
- "linux"
34
- when "windows"
35
- "windows"
36
- else
37
- raise "Unsupported OS: #{Sass::Platform::OS}"
38
- end
39
-
40
- arch = case Sass::Platform::ARCH
41
- when "x86_64"
42
- "x64"
43
- when "i386"
44
- "ia32"
45
- else
46
- raise "Unsupported Arch: #{Sass::Platform::ARCH}"
47
- end
48
-
49
- ext = case os
50
- when "windows"
51
- "zip"
52
- else
53
- "tar.gz"
54
- end
17
+ private
55
18
 
56
- url = "https://github.com/#{repo}/releases/download/#{release}/sass_embedded-#{release}-#{os}-#{arch}.#{ext}"
19
+ def api(url)
20
+ headers = {}
21
+ headers['Authorization'] = "token #{ENV['GITHUB_TOKEN']}" if ENV['GITHUB_TOKEN']
22
+ URI.parse(url).open(headers) do |file|
23
+ JSON.parse file.read
24
+ end
25
+ end
57
26
 
58
- begin
59
- download url
60
- rescue
61
- raise "Failed to download: #{url}"
62
- end
63
- end
27
+ def download(url)
28
+ URI.parse(url).open do |source|
29
+ File.open(File.absolute_path(File.basename(url), __dir__), 'wb') do |destination|
30
+ destination.write source.read
31
+ end
32
+ end
33
+ rescue StandardError
34
+ raise "Failed to download: #{url}"
35
+ end
64
36
 
65
- def download_protoc
66
- repo = "protocolbuffers/protobuf"
67
-
68
- tag = URI.open('https://github.com/protocolbuffers/protobuf/releases/latest') { |file|
69
- File.basename file.base_uri.to_s
70
- }
71
-
72
- release = tag[1..-1]
73
-
74
- os = case Sass::Platform::OS
75
- when "darwin"
76
- "osx"
77
- when "linux"
78
- "linux"
79
- when "windows"
80
- "win"
81
- else
82
- raise "Unsupported OS: #{Sass::Platform::OS}"
83
- end
84
-
85
- arch = case Sass::Platform::ARCH
86
- when "aarch64"
87
- "aarch_64"
88
- when "sparcv9"
89
- "s390"
90
- when "i386"
91
- "x86_32"
92
- when "x86_64"
93
- "x86_64"
94
- when "powerpc64"
95
- "ppcle_64"
96
- else
97
- raise "Unsupported Arch: #{Sass::Platform::ARCH}"
98
- end
99
-
100
- os_arch = case os
101
- when "win"
102
- os + arch.split('_').last
37
+ def download_sass_embedded
38
+ repo = 'sass/dart-sass-embedded'
39
+
40
+ release = api("https://api.github.com/repos/#{repo}/releases")[0]['tag_name']
41
+
42
+ os = case Sass::Platform::OS
43
+ when 'darwin'
44
+ 'macos'
45
+ when 'linux'
46
+ 'linux'
47
+ when 'windows'
48
+ 'windows'
49
+ else
50
+ raise "Unsupported OS: #{Sass::Platform::OS}"
51
+ end
52
+
53
+ arch = case Sass::Platform::ARCH
54
+ when 'x86_64'
55
+ 'x64'
56
+ when 'i386'
57
+ 'ia32'
58
+ else
59
+ raise "Unsupported Arch: #{Sass::Platform::ARCH}"
60
+ end
61
+
62
+ ext = case os
63
+ when 'windows'
64
+ 'zip'
103
65
  else
104
- os + '-' + arch
66
+ 'tar.gz'
105
67
  end
106
68
 
107
- ext = "zip"
69
+ url = "https://github.com/#{repo}/releases/download/#{release}/sass_embedded-#{release}-#{os}-#{arch}.#{ext}"
70
+ download url
71
+ end
108
72
 
109
- url = "https://github.com/#{repo}/releases/download/#{tag}/protoc-#{release}-#{os_arch}.#{ext}"
73
+ def download_protoc
74
+ repo = 'protocolbuffers/protobuf'
75
+
76
+ tag = URI.parse("https://github.com/#{repo}/releases/latest").open do |file|
77
+ File.basename file.base_uri.to_s
78
+ end
79
+
80
+ release = tag[1..-1]
81
+
82
+ os = case Sass::Platform::OS
83
+ when 'darwin'
84
+ 'osx'
85
+ when 'linux'
86
+ 'linux'
87
+ when 'windows'
88
+ 'win'
89
+ else
90
+ raise "Unsupported OS: #{Sass::Platform::OS}"
91
+ end
92
+
93
+ arch = case Sass::Platform::ARCH
94
+ when 'aarch64'
95
+ 'aarch_64'
96
+ when 'sparcv9'
97
+ 's390'
98
+ when 'i386'
99
+ 'x86_32'
100
+ when 'x86_64'
101
+ 'x86_64'
102
+ when 'powerpc64'
103
+ 'ppcle_64'
104
+ else
105
+ raise "Unsupported Arch: #{Sass::Platform::ARCH}"
106
+ end
107
+
108
+ os_arch = case os
109
+ when 'win'
110
+ os + arch.split('_').last
111
+ else
112
+ "#{os}-#{arch}"
113
+ end
114
+
115
+ ext = 'zip'
116
+
117
+ url = "https://github.com/#{repo}/releases/download/#{tag}/protoc-#{release}-#{os_arch}.#{ext}"
118
+ download url
119
+ end
110
120
 
111
- begin
112
- download url
113
- rescue
114
- raise "Failed to download: #{url}"
115
- end
116
- end
121
+ def download_embedded_sass_proto
122
+ url = 'https://raw.githubusercontent.com/sass/embedded-protocol/HEAD/embedded_sass.proto'
123
+ download url
124
+ end
117
125
 
118
- def download_embedded_sass_proto
119
- url = "https://raw.githubusercontent.com/sass/embedded-protocol/HEAD/embedded_sass.proto"
120
- download url
126
+ end
121
127
  end
122
128
 
123
- system("make", "-C", __dir__, "distclean")
124
- download_sass_embedded
125
- download_protoc
126
- download_embedded_sass_proto
127
- system("make", "-C", __dir__, "install")
128
-
129
- File.open(File.absolute_path("sass_embedded.#{RbConfig::CONFIG['DLEXT']}", __dir__), "w") {}
130
-
131
- $makefile_created = true
129
+ Sass::Extconf.new
data/lib/sass.rb CHANGED
@@ -3,9 +3,9 @@
3
3
  module Sass
4
4
  # The global include_paths for Sass files. This is meant for plugins and
5
5
  # libraries to register the paths to their Sass stylesheets to that they may
6
- # be `@imported`. This includes path is used by every instance of
7
- # {Sass::Embedded::Compiler}. They are lower-precedence than any includes
8
- # paths passed in via the `:includes_paths` option.
6
+ # be `@imported`. This include path is used by every instance of
7
+ # {Sass::Embedded}. They are lower-precedence than any include paths passed
8
+ # in via the `:include_paths` option.
9
9
  #
10
10
  # If the `SASS_PATH` environment variable is set,
11
11
  # the initial value of `include_paths` will be initialized based on that.
@@ -13,25 +13,30 @@ module Sass
13
13
  # (semicolon-separated on Windows).
14
14
  #
15
15
  # @example
16
- # Sass.include_paths << File.dirname(__FILE__ + '/sass')
16
+ # Sass.include_paths << File.dirname(__FILE__) + '/sass'
17
17
  # @return [Array<String, Pathname>]
18
18
  def self.include_paths
19
- @includes_paths ||= if ENV['SASS_PATH']
20
- ENV['SASS_PATH'].split(File::PATH_SEPARATOR)
21
- else
22
- []
23
- end
19
+ @include_paths ||= if ENV['SASS_PATH']
20
+ ENV['SASS_PATH'].split(File::PATH_SEPARATOR)
21
+ else
22
+ []
23
+ end
24
24
  end
25
25
 
26
- def self.render options
27
- @compiler ||= Sass::Embedded::Compiler.new
28
- @compiler.render options
26
+ def self.render(options)
27
+ unless defined? @embedded
28
+ @embedded = Sass::Embedded.new
29
+ at_exit do
30
+ @embedded.close
31
+ end
32
+ end
33
+ @embedded.render options
29
34
  end
30
35
  end
31
36
 
32
- require_relative "sass/version"
33
- require_relative "sass/error"
34
- require_relative "sass/platform"
35
- require_relative "sass/util"
36
- require_relative "sass/embedded/transport"
37
- require_relative "sass/embedded/compiler"
37
+ require_relative 'sass/version'
38
+ require_relative 'sass/error'
39
+ require_relative 'sass/platform'
40
+ require_relative 'sass/util'
41
+ require_relative 'sass/transport'
42
+ require_relative 'sass/embedded'
@@ -0,0 +1,237 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ class Embedded
5
+ def initialize
6
+ @transport = Transport.new
7
+ @id_semaphore = Mutex.new
8
+ @id = 0
9
+ end
10
+
11
+ def render(options)
12
+ start = Sass::Util.now
13
+
14
+ raise Sass::NotRenderedError, 'Either :data or :file must be set.' if options[:file].nil? && options[:data].nil?
15
+
16
+ string = if options[:data]
17
+ Sass::EmbeddedProtocol::InboundMessage::CompileRequest::StringInput.new(
18
+ source: options[:data],
19
+ url: options[:file] ? Sass::Util.file_uri(options[:file]) : 'stdin',
20
+ syntax: options[:indented_syntax] == true ? Sass::EmbeddedProtocol::Syntax::INDENTED : Sass::EmbeddedProtocol::Syntax::SCSS
21
+ )
22
+ end
23
+
24
+ path = options[:data] ? nil : options[:file]
25
+
26
+ style = case options[:output_style]&.to_sym
27
+ when :expanded, nil
28
+ Sass::EmbeddedProtocol::OutputStyle::EXPANDED
29
+ when :compressed
30
+ Sass::EmbeddedProtocol::OutputStyle::COMPRESSED
31
+ when :nested, :compact
32
+ raise Sass::UnsupportedValue, "#{options[:output_style]} is not a supported :output_style"
33
+ else
34
+ raise Sass::InvalidStyleError, "#{options[:output_style]} is not a valid :output_style"
35
+ end
36
+
37
+ source_map = options[:source_map].is_a?(String) || (options[:source_map] == true && !options[:out_file].nil?)
38
+
39
+ # 1. Loading a file relative to the file in which the @use or @import appeared.
40
+ # 2. Each custom importer.
41
+ # 3. Loading a file relative to the current working directory.
42
+ # 4. Each load path in includePaths
43
+ # 5. Each load path specified in the SASS_PATH environment variable, which should be semicolon-separated on Windows and colon-separated elsewhere.
44
+ importers = (if options[:importer]
45
+ [
46
+ Sass::EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new(importer_id: 0)
47
+ ]
48
+ else
49
+ []
50
+ end).concat(
51
+ (options[:include_paths] || []).concat(Sass.include_paths)
52
+ .map do |include_path|
53
+ Sass::EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new(
54
+ path: File.absolute_path(include_path)
55
+ )
56
+ end
57
+ )
58
+
59
+ signatures = []
60
+ functions = {}
61
+ options[:functions]&.each do |signature, function|
62
+ signatures.push signature
63
+ functions[signature.to_s.split('(')[0].chomp] = function
64
+ end
65
+
66
+ compilation_id = next_id
67
+
68
+ compile_request = Sass::EmbeddedProtocol::InboundMessage::CompileRequest.new(
69
+ id: compilation_id,
70
+ string: string,
71
+ path: path,
72
+ style: style,
73
+ source_map: source_map,
74
+ importers: importers,
75
+ global_functions: options[:functions] ? signatures : [],
76
+ alert_color: true,
77
+ alert_ascii: true
78
+ )
79
+
80
+ response = @transport.send compile_request, compilation_id
81
+
82
+ file = options[:file] || 'stdin'
83
+ canonicalizations = {}
84
+ imports = {}
85
+
86
+ loop do
87
+ case response
88
+ when Sass::EmbeddedProtocol::OutboundMessage::CompileResponse
89
+ break
90
+ when Sass::EmbeddedProtocol::OutboundMessage::CanonicalizeRequest
91
+ url = Sass::Util.file_uri(File.absolute_path(response.url, File.dirname(file)))
92
+
93
+ if canonicalizations.key? url
94
+ canonicalizations[url].id = response.id
95
+ else
96
+ resolved = nil
97
+ options[:importer].each do |importer|
98
+ begin
99
+ resolved = importer.call response.url, file
100
+ rescue StandardError => e
101
+ resolved = e
102
+ end
103
+ break if resolved
104
+ end
105
+ if resolved.nil?
106
+ canonicalizations[url] = Sass::EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
107
+ id: response.id,
108
+ url: url
109
+ )
110
+ elsif resolved.is_a? StandardError
111
+ canonicalizations[url] = Sass::EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
112
+ id: response.id,
113
+ error: resolved.message
114
+ )
115
+ elsif resolved.key? :contents
116
+ canonicalizations[url] = Sass::EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
117
+ id: response.id,
118
+ url: url
119
+ )
120
+ imports[url] = Sass::EmbeddedProtocol::InboundMessage::ImportResponse.new(
121
+ id: response.id,
122
+ success: Sass::EmbeddedProtocol::InboundMessage::ImportResponse::ImportSuccess.new(
123
+ contents: resolved[:contents],
124
+ syntax: Sass::EmbeddedProtocol::Syntax::SCSS,
125
+ source_map_url: nil
126
+ )
127
+ )
128
+ elsif resolved.key? :file
129
+ canonicalized_url = Sass::Util.file_uri(resolved[:file])
130
+ canonicalizations[url] = Sass::EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
131
+ id: response.id,
132
+ url: canonicalized_url
133
+ )
134
+ imports[canonicalized_url] = Sass::EmbeddedProtocol::InboundMessage::ImportResponse.new(
135
+ id: response.id,
136
+ success: Sass::EmbeddedProtocol::InboundMessage::ImportResponse::ImportSuccess.new(
137
+ contents: File.read(resolved[:file]),
138
+ syntax: Sass::EmbeddedProtocol::Syntax::SCSS,
139
+ source_map_url: nil
140
+ )
141
+ )
142
+ else
143
+ canonicalizations[url] = Sass::EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
144
+ id: response.id,
145
+ error: "Unexpected value returned from importer: #{resolved}"
146
+ )
147
+ end
148
+ end
149
+
150
+ response = @transport.send canonicalizations[url], compilation_id
151
+ when Sass::EmbeddedProtocol::OutboundMessage::ImportRequest
152
+ url = response.url
153
+
154
+ if imports.key? url
155
+ imports[url].id = response.id
156
+ else
157
+ imports[url] = Sass::EmbeddedProtocol::InboundMessage::ImportResponse.new(
158
+ id: response.id,
159
+ error: "Failed to import: #{url}"
160
+ )
161
+ end
162
+
163
+ response = @transport.send imports[url], compilation_id
164
+ when Sass::EmbeddedProtocol::OutboundMessage::FunctionCallRequest
165
+ begin
166
+ message = Sass::EmbeddedProtocol::InboundMessage::FunctionCallResponse.new(
167
+ id: response.id,
168
+ success: functions[response.name].call(*response.arguments)
169
+ )
170
+ rescue StandardError => e
171
+ message = Sass::EmbeddedProtocol::InboundMessage::FunctionCallResponse.new(
172
+ id: response.id,
173
+ error: e.message
174
+ )
175
+ end
176
+
177
+ response = @transport.send message, compilation_id
178
+ when Sass::EmbeddedProtocol::ProtocolError
179
+ raise Sass::ProtocolError, response.message
180
+ else
181
+ raise Sass::ProtocolError, "Unexpected packet received: #{response}"
182
+ end
183
+ end
184
+
185
+ if response.failure
186
+ raise Sass::CompilationError.new(
187
+ response.failure.message,
188
+ response.failure.formatted,
189
+ response.failure.span ? response.failure.span.url : nil,
190
+ response.failure.span ? response.failure.span.start.line + 1 : nil,
191
+ response.failure.span ? response.failure.span.start.column + 1 : nil,
192
+ 1
193
+ )
194
+ end
195
+
196
+ finish = Sass::Util.now
197
+
198
+ {
199
+ css: response.success.css,
200
+ map: response.success.source_map,
201
+ stats: {
202
+ entry: options[:file] || 'data',
203
+ start: start,
204
+ end: finish,
205
+ duration: finish - start
206
+ }
207
+ }
208
+ end
209
+
210
+ def close
211
+ @transport.close
212
+ nil
213
+ end
214
+
215
+ private
216
+
217
+ def info
218
+ version_response = @transport.send Sass::EmbeddedProtocol::InboundMessage::VersionRequest.new(
219
+ id: next_id
220
+ )
221
+ {
222
+ compiler_version: version_response.compiler_version,
223
+ protocol_version: version_response.protocol_version,
224
+ implementation_name: version_response.implementation_name,
225
+ implementation_version: version_response.implementation_version
226
+ }
227
+ end
228
+
229
+ def next_id
230
+ @id_semaphore.synchronize do
231
+ @id += 1
232
+ @id = 0 if @id == Transport::PROTOCOL_ERROR_ID
233
+ @id
234
+ end
235
+ end
236
+ end
237
+ end