sass-embedded 0.8.1 → 0.9.2

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.
data/lib/sass/embedded.rb CHANGED
@@ -2,10 +2,17 @@
2
2
 
3
3
  require 'base64'
4
4
  require 'json'
5
+ require_relative 'embedded/channel'
6
+ require_relative 'embedded/compile_context'
7
+ require_relative 'embedded/error'
8
+ require_relative 'embedded/result'
9
+ require_relative 'embedded/util'
10
+ require_relative 'embedded/version'
11
+ require_relative 'embedded/version_context'
5
12
 
6
13
  module Sass
7
14
  # The {Embedded} host for using dart-sass-embedded. Each instance creates
8
- # its own {Transport}.
15
+ # its own {Channel}.
9
16
  #
10
17
  # @example
11
18
  # embedded = Sass::Embedded.new
@@ -13,17 +20,23 @@ module Sass
13
20
  # result = embedded.render(file: 'style.css')
14
21
  # embedded.close
15
22
  class Embedded
23
+ def self.include_paths
24
+ @include_paths ||= if ENV['SASS_PATH']
25
+ ENV['SASS_PATH'].split(File::PATH_SEPARATOR)
26
+ else
27
+ []
28
+ end
29
+ end
30
+
16
31
  def initialize
17
- @transport = Transport.new
18
- @id_semaphore = Mutex.new
19
- @id = 0
32
+ @channel = Channel.new
20
33
  end
21
34
 
22
35
  # The {Embedded#info} method.
23
36
  #
24
37
  # @raise [ProtocolError]
25
38
  def info
26
- @info ||= VersionContext.new(@transport, next_id).receive_message
39
+ @info ||= VersionContext.new(@channel).receive_message
27
40
  end
28
41
 
29
42
  # The {Embedded#render} method.
@@ -55,7 +68,7 @@ module Sass
55
68
  indent_width = parse_indent_width(indent_width)
56
69
  linefeed = parse_linefeed(linefeed)
57
70
 
58
- message = CompileContext.new(@transport, next_id,
71
+ message = CompileContext.new(@channel,
59
72
  data: data,
60
73
  file: file,
61
74
  indented_syntax: indented_syntax,
@@ -109,11 +122,11 @@ module Sass
109
122
  end
110
123
 
111
124
  def close
112
- @transport.close
125
+ @channel.close
113
126
  end
114
127
 
115
128
  def closed?
116
- @transport.closed?
129
+ @channel.closed?
117
130
  end
118
131
 
119
132
  private
@@ -239,13 +252,5 @@ module Sass
239
252
  raise ArgumentError, 'linefeed must be one of :lf, :lfcr, :cr, :crlf'
240
253
  end
241
254
  end
242
-
243
- def next_id
244
- @id_semaphore.synchronize do
245
- @id += 1
246
- @id = 0 if @id == Compiler::PROTOCOL_ERROR_ID
247
- @id
248
- end
249
- end
250
255
  end
251
256
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../ext/sass/embedded_sass_pb'
4
+
5
+ module Sass
6
+ module EmbeddedProtocol
7
+ PROTOCOL_ERROR_ID = 4_294_967_295
8
+ end
9
+ end
data/lib/sass.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'sass/embedded'
4
+
3
5
  # The Sass module. This communicates with Embedded Dart Sass using
4
6
  # the Embedded Sass protocol.
5
7
  module Sass
@@ -19,11 +21,7 @@ module Sass
19
21
  # Sass.include_paths << File.dirname(__FILE__) + '/sass'
20
22
  # @return [Array]
21
23
  def include_paths
22
- @include_paths ||= if ENV['SASS_PATH']
23
- ENV['SASS_PATH'].split(File::PATH_SEPARATOR)
24
- else
25
- []
26
- end
24
+ Embedded.include_paths
27
25
  end
28
26
 
29
27
  # The global {.info} method. This instantiates a global {Embedded} instance
@@ -31,7 +29,7 @@ module Sass
31
29
  #
32
30
  # @raise [ProtocolError]
33
31
  def info
34
- embedded.info
32
+ instance.info
35
33
  end
36
34
 
37
35
  # The global {.render} method. This instantiates a global {Embedded} instance
@@ -47,28 +45,21 @@ module Sass
47
45
  # @raise [ProtocolError]
48
46
  # @raise [RenderError]
49
47
  def render(**kwargs)
50
- embedded.render(**kwargs)
48
+ instance.render(**kwargs)
51
49
  end
52
50
 
53
51
  private
54
52
 
55
- def embedded
56
- return @embedded if defined?(@embedded) && !@embedded.closed?
57
-
58
- @embedded = Sass::Embedded.new
53
+ def instance
54
+ if @instance.nil?
55
+ @instance = Embedded.new
56
+ at_exit do
57
+ @instance.close
58
+ end
59
+ elsif @instance.closed?
60
+ @instance = Embedded.new
61
+ end
62
+ @instance
59
63
  end
60
64
  end
61
65
  end
62
-
63
- require_relative 'sass/version'
64
- require_relative 'sass/platform'
65
- require_relative 'sass/compiler'
66
- require_relative 'sass/util'
67
- require_relative 'sass/struct'
68
- require_relative 'sass/result'
69
- require_relative 'sass/error'
70
- require_relative 'sass/transport'
71
- require_relative 'sass/observer'
72
- require_relative 'sass/info'
73
- require_relative 'sass/compile'
74
- require_relative 'sass/embedded'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sass-embedded
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - なつき
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-26 00:00:00.000000000 Z
11
+ date: 2021-10-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-protobuf
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 3.18.0
19
+ version: 3.18.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 3.18.0
26
+ version: 3.18.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -72,28 +72,28 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 1.21.0
75
+ version: 1.22.1
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 1.21.0
82
+ version: 1.22.1
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rubocop-minitest
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 0.15.0
89
+ version: 0.15.2
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 0.15.0
96
+ version: 0.15.2
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rubocop-performance
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -138,24 +138,26 @@ files:
138
138
  - ext/sass/unzip.vbs
139
139
  - lib/sass-embedded.rb
140
140
  - lib/sass.rb
141
- - lib/sass/compile.rb
142
- - lib/sass/compiler.rb
143
141
  - lib/sass/embedded.rb
144
- - lib/sass/error.rb
145
- - lib/sass/info.rb
146
- - lib/sass/observer.rb
147
- - lib/sass/platform.rb
148
- - lib/sass/result.rb
149
- - lib/sass/struct.rb
150
- - lib/sass/transport.rb
151
- - lib/sass/util.rb
152
- - lib/sass/version.rb
142
+ - lib/sass/embedded/channel.rb
143
+ - lib/sass/embedded/compile_context.rb
144
+ - lib/sass/embedded/compiler.rb
145
+ - lib/sass/embedded/compiler/path.rb
146
+ - lib/sass/embedded/compiler/requirements.rb
147
+ - lib/sass/embedded/error.rb
148
+ - lib/sass/embedded/observer.rb
149
+ - lib/sass/embedded/platform.rb
150
+ - lib/sass/embedded/result.rb
151
+ - lib/sass/embedded/util.rb
152
+ - lib/sass/embedded/version.rb
153
+ - lib/sass/embedded/version_context.rb
154
+ - lib/sass/embedded_protocol.rb
153
155
  homepage: https://github.com/ntkme/sass-embedded-host-ruby
154
156
  licenses:
155
157
  - MIT
156
158
  metadata:
157
- documentation_uri: https://www.rubydoc.info/gems/sass-embedded/0.8.1
158
- source_code_uri: https://github.com/ntkme/sass-embedded-host-ruby/tree/v0.8.1
159
+ documentation_uri: https://www.rubydoc.info/gems/sass-embedded/0.9.2
160
+ source_code_uri: https://github.com/ntkme/sass-embedded-host-ruby/tree/v0.9.2
159
161
  funding_uri: https://github.com/sponsors/ntkme
160
162
  post_install_message:
161
163
  rdoc_options: []
data/lib/sass/compile.rb DELETED
@@ -1,249 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Sass
4
- # The {Observer} for {Embedded#render}.
5
- class CompileContext
6
- include Observer
7
-
8
- def initialize(transport, id,
9
- data:,
10
- file:,
11
- indented_syntax:,
12
- include_paths:,
13
- output_style:,
14
- source_map:,
15
- out_file:,
16
- functions:,
17
- importer:)
18
- raise ArgumentError, 'either data or file must be set' if file.nil? && data.nil?
19
-
20
- @id = id
21
- @data = data
22
- @file = file
23
- @indented_syntax = indented_syntax
24
- @include_paths = include_paths
25
- @output_style = output_style
26
- @source_map = source_map
27
- @out_file = out_file
28
- @global_functions = functions.keys
29
- @functions = functions.transform_keys do |key|
30
- key.to_s.split('(')[0].chomp
31
- end
32
- @importer = importer
33
- @import_responses = {}
34
-
35
- super(transport)
36
-
37
- send_message compile_request
38
- end
39
-
40
- def update(error, message)
41
- raise error unless error.nil?
42
-
43
- case message
44
- when EmbeddedProtocol::OutboundMessage::CompileResponse
45
- return unless message.id == @id
46
-
47
- Thread.new do
48
- super(nil, message)
49
- end
50
- when EmbeddedProtocol::OutboundMessage::LogEvent
51
- return unless message.compilation_id == @id && $stderr.tty?
52
-
53
- warn message.formatted
54
- when EmbeddedProtocol::OutboundMessage::CanonicalizeRequest
55
- return unless message.compilation_id == @id
56
-
57
- Thread.new do
58
- send_message canonicalize_response message
59
- end
60
- when EmbeddedProtocol::OutboundMessage::ImportRequest
61
- return unless message.compilation_id == @id
62
-
63
- Thread.new do
64
- send_message import_response message
65
- end
66
- when EmbeddedProtocol::OutboundMessage::FileImportRequest
67
- raise NotImplementedError, 'FileImportRequest is not implemented'
68
- when EmbeddedProtocol::OutboundMessage::FunctionCallRequest
69
- return unless message.compilation_id == @id
70
-
71
- Thread.new do
72
- send_message function_call_response message
73
- end
74
- end
75
- rescue StandardError => e
76
- Thread.new do
77
- super(e, nil)
78
- end
79
- end
80
-
81
- private
82
-
83
- def compile_request
84
- EmbeddedProtocol::InboundMessage::CompileRequest.new(
85
- id: @id,
86
- string: string,
87
- path: path,
88
- style: style,
89
- source_map: source_map,
90
- importers: importers,
91
- global_functions: global_functions,
92
- alert_color: $stderr.tty?,
93
- alert_ascii: Platform::OS == 'windows'
94
- )
95
- end
96
-
97
- def canonicalize_response(canonicalize_request)
98
- url = Util.file_uri_from_path(File.absolute_path(canonicalize_request.url, (@file.nil? ? 'stdin' : @file)))
99
-
100
- begin
101
- result = @importer[canonicalize_request.importer_id].call canonicalize_request.url, @file
102
- raise result if result.is_a? StandardError
103
- rescue StandardError => e
104
- return EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
105
- id: canonicalize_request.id,
106
- error: e.message
107
- )
108
- end
109
-
110
- if result&.key? :contents
111
- @import_responses[url] = EmbeddedProtocol::InboundMessage::ImportResponse.new(
112
- id: canonicalize_request.id,
113
- success: EmbeddedProtocol::InboundMessage::ImportResponse::ImportSuccess.new(
114
- contents: result[:contents],
115
- syntax: EmbeddedProtocol::Syntax::SCSS,
116
- source_map_url: nil
117
- )
118
- )
119
- EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
120
- id: canonicalize_request.id,
121
- url: url
122
- )
123
- elsif result&.key? :file
124
- canonicalized_url = Util.file_uri_from_path(File.absolute_path(result[:file]))
125
-
126
- # TODO: FileImportRequest is not supported yet.
127
- # Workaround by reading contents and return it when server asks
128
- @import_responses[canonicalized_url] = EmbeddedProtocol::InboundMessage::ImportResponse.new(
129
- id: canonicalize_request.id,
130
- success: EmbeddedProtocol::InboundMessage::ImportResponse::ImportSuccess.new(
131
- contents: File.read(result[:file]),
132
- syntax: EmbeddedProtocol::Syntax::SCSS,
133
- source_map_url: nil
134
- )
135
- )
136
-
137
- EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
138
- id: canonicalize_request.id,
139
- url: canonicalized_url
140
- )
141
- else
142
- EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
143
- id: canonicalize_request.id
144
- )
145
- end
146
- end
147
-
148
- def import_response(import_request)
149
- url = import_request.url
150
-
151
- if @import_responses.key? url
152
- @import_responses[url].id = import_request.id
153
- else
154
- @import_responses[url] = EmbeddedProtocol::InboundMessage::ImportResponse.new(
155
- id: import_request.id,
156
- error: "Failed to import: #{url}"
157
- )
158
- end
159
-
160
- @import_responses[url]
161
- end
162
-
163
- def function_call_response(function_call_request)
164
- # TODO: convert argument_list to **kwargs
165
- EmbeddedProtocol::InboundMessage::FunctionCallResponse.new(
166
- id: function_call_request.id,
167
- success: @functions[function_call_request.name].call(*function_call_request.arguments),
168
- accessed_argument_lists: function_call_request.arguments
169
- .filter { |argument| argument.value == :argument_list }
170
- .map { |argument| argument.argument_list.id }
171
- )
172
- rescue StandardError => e
173
- EmbeddedProtocol::InboundMessage::FunctionCallResponse.new(
174
- id: function_call_request.id,
175
- error: e.message
176
- )
177
- end
178
-
179
- def syntax
180
- if @indented_syntax == true
181
- EmbeddedProtocol::Syntax::INDENTED
182
- else
183
- EmbeddedProtocol::Syntax::SCSS
184
- end
185
- end
186
-
187
- def url
188
- return if @file.nil?
189
-
190
- Util.file_uri_from_path File.absolute_path @file
191
- end
192
-
193
- def string
194
- return if @data.nil?
195
-
196
- EmbeddedProtocol::InboundMessage::CompileRequest::StringInput.new(
197
- source: @data,
198
- url: url,
199
- syntax: syntax
200
- )
201
- end
202
-
203
- def path
204
- @file if @data.nil?
205
- end
206
-
207
- def style
208
- case @output_style&.to_sym
209
- when :expanded
210
- EmbeddedProtocol::OutputStyle::EXPANDED
211
- when :compressed
212
- EmbeddedProtocol::OutputStyle::COMPRESSED
213
- else
214
- raise ArgumentError, 'output_style must be one of :expanded, :compressed'
215
- end
216
- end
217
-
218
- def source_map
219
- @source_map.is_a?(String) || (@source_map == true && !@out_file.nil?)
220
- end
221
-
222
- attr_reader :global_functions
223
-
224
- # Order
225
- # 1. Loading a file relative to the file in which the @use or @import appeared.
226
- # 2. Each custom importer.
227
- # 3. Loading a file relative to the current working directory.
228
- # 4. Each load path in includePaths
229
- # 5. Each load path specified in the SASS_PATH environment variable, which should
230
- # be semicolon-separated on Windows and colon-separated elsewhere.
231
- def importers
232
- custom_importers = @importer.map.with_index do |_, id|
233
- EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new(
234
- importer_id: id
235
- )
236
- end
237
-
238
- include_path_importers = @include_paths
239
- .concat(Sass.include_paths)
240
- .map do |include_path|
241
- EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new(
242
- path: File.absolute_path(include_path)
243
- )
244
- end
245
-
246
- custom_importers.concat include_path_importers
247
- end
248
- end
249
- end
data/lib/sass/compiler.rb DELETED
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Sass
4
- module Compiler
5
- DART_SASS_EMBEDDED = File.absolute_path(
6
- "../../ext/sass/sass_embedded/dart-sass-embedded#{Platform::OS == 'windows' ? '.bat' : ''}", __dir__
7
- )
8
-
9
- PROTOCOL_ERROR_ID = 4_294_967_295
10
-
11
- REQUIREMENTS = '~> 1.0.0-beta.11'
12
- end
13
- end
data/lib/sass/error.rb DELETED
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Sass
4
- class Error < StandardError; end
5
-
6
- class ProtocolError < Error; end
7
-
8
- # The {Error} raised by {Embedded#render}.
9
- class RenderError < Error
10
- attr_reader :formatted, :file, :line, :column, :status
11
-
12
- def initialize(message, formatted, file, line, column, status)
13
- super(message)
14
- @formatted = formatted
15
- @file = file
16
- @line = line
17
- @column = column
18
- @status = status
19
- end
20
-
21
- def backtrace
22
- return nil if super.nil?
23
-
24
- ["#{@file}:#{@line}:#{@column}"] + super
25
- end
26
- end
27
- end
data/lib/sass/info.rb DELETED
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Sass
4
- # The {Observer} for {Embedded#info}.
5
- class VersionContext
6
- include Observer
7
-
8
- def initialize(transport, id)
9
- @id = id
10
-
11
- super(transport)
12
-
13
- send_message EmbeddedProtocol::InboundMessage::VersionRequest.new(id: @id)
14
- end
15
-
16
- def update(error, message)
17
- raise error unless error.nil?
18
-
19
- case message
20
- when EmbeddedProtocol::OutboundMessage::VersionResponse
21
- return unless message.id == @id
22
-
23
- Thread.new do
24
- super(nil, message)
25
- end
26
- end
27
- rescue StandardError => e
28
- Thread.new do
29
- super(e, nil)
30
- end
31
- end
32
- end
33
- end
data/lib/sass/observer.rb DELETED
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Sass
4
- # The {Observer} module for receiving messages from {Transport}.
5
- module Observer
6
- def initialize(transport)
7
- @transport = transport
8
- @mutex = Mutex.new
9
- @condition_variable = ConditionVariable.new
10
- @error = nil
11
- @message = nil
12
- @transport.add_observer self
13
- end
14
-
15
- def receive_message
16
- @mutex.synchronize do
17
- @condition_variable.wait(@mutex) if @error.nil? && @message.nil?
18
- end
19
-
20
- raise @error unless @error.nil?
21
-
22
- @message
23
- end
24
-
25
- def update(error, message)
26
- @transport.delete_observer self
27
- @mutex.synchronize do
28
- @error = error
29
- @message = message
30
- @condition_variable.broadcast
31
- end
32
- end
33
-
34
- private
35
-
36
- def send_message(message)
37
- @transport.send_message(message)
38
- end
39
- end
40
- end
data/lib/sass/platform.rb DELETED
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Sass
4
- module Platform
5
- OS = case RbConfig::CONFIG['host_os'].downcase
6
- when /linux/
7
- 'linux'
8
- when /darwin/
9
- 'darwin'
10
- when /freebsd/
11
- 'freebsd'
12
- when /netbsd/
13
- 'netbsd'
14
- when /openbsd/
15
- 'openbsd'
16
- when /dragonfly/
17
- 'dragonflybsd'
18
- when /sunos|solaris/
19
- 'solaris'
20
- when /mingw|mswin/
21
- 'windows'
22
- else
23
- RbConfig::CONFIG['host_os'].downcase
24
- end
25
-
26
- OSVERSION = RbConfig::CONFIG['host_os'].gsub(/[^\d]/, '').to_i
27
-
28
- CPU = RbConfig::CONFIG['host_cpu']
29
-
30
- ARCH = case CPU.downcase
31
- when /amd64|x86_64|x64/
32
- 'x86_64'
33
- when /i\d86|x86|i86pc/
34
- 'i386'
35
- when /ppc64|powerpc64/
36
- 'powerpc64'
37
- when /ppc|powerpc/
38
- 'powerpc'
39
- when /sparcv9|sparc64/
40
- 'sparcv9'
41
- when /arm64|aarch64/ # MacOS calls it "arm64", other operating systems "aarch64"
42
- 'aarch64'
43
- when /^arm/
44
- if OS == 'darwin' # Ruby before 3.0 reports "arm" instead of "arm64" as host_cpu on darwin
45
- 'aarch64'
46
- else
47
- 'arm'
48
- end
49
- else
50
- RbConfig::CONFIG['host_cpu']
51
- end
52
- end
53
- end