sass-embedded 0.4.0 → 0.4.1

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: c9afb73da6288ecf0360685cc9ddb4c072eb8840da50acaa8a52b67f09998e6c
4
- data.tar.gz: 1a20d885e2e9f55ffd861f9428499f4c3bdea64a4aea81e44f356af8be69eccc
3
+ metadata.gz: 44a04b95b0d29cda95382a09cb00512ff6c2bb3f2c93b04f6171678856f648b7
4
+ data.tar.gz: 944fefc7cc7507a20ebea9154c412bd99cc5cf9e2d698d604bcf0dd71e287aeb
5
5
  SHA512:
6
- metadata.gz: 679cfc5b502de2fdc5b33c8117b7e1d68f94acd62c7afbe04ebb17f9bceacdc677e8b35197cf239f92fed4e3d523468d71798d899c360d8402be127bdb50ac48
7
- data.tar.gz: e1d698b3980914299ee2ce570bd1f109a875859c147f8930366df8e2dabcae94f0e0795339f6614f3f7828e365c191ba24554e30869e4bd106f565f1cbbb9af2
6
+ metadata.gz: a6088c2f97962305cea6dadcf4e5b5cb24d8332b9de55a2c42ebcc7c1929661d84dc40598e4167b5c74489eeeb898e8f47cdb638c0492a63c22124b7b14f1641
7
+ data.tar.gz: 2894b4ae45d5f2eea15d99a403b1641f6ec5192d79b06765b3c7d765aa11255c3513f2f754d8405a8c9b32dc51f6f6ace8caf928f412e6e1334c0d979c6ae0b8
data/lib/sass.rb CHANGED
@@ -2,43 +2,51 @@
2
2
 
3
3
  # The Sass module
4
4
  module Sass
5
- # The global include_paths for Sass files. This is meant for plugins and
6
- # libraries to register the paths to their Sass stylesheets to that they may
7
- # be `@imported`. This include path is used by every instance of
8
- # {Sass::Embedded}. They are lower-precedence than any include paths passed
9
- # in via the `:include_paths` option.
10
- #
11
- # If the `SASS_PATH` environment variable is set,
12
- # the initial value of `include_paths` will be initialized based on that.
13
- # The variable should be a colon-separated list of path names
14
- # (semicolon-separated on Windows).
15
- #
16
- # @example
17
- # Sass.include_paths << File.dirname(__FILE__) + '/sass'
18
- # @return [Array<String, Pathname>]
19
- def self.include_paths
20
- @include_paths ||= if ENV['SASS_PATH']
21
- ENV['SASS_PATH'].split(File::PATH_SEPARATOR)
22
- else
23
- []
24
- end
25
- end
5
+ class << self
6
+ # The global include_paths for Sass files. This is meant for plugins and
7
+ # libraries to register the paths to their Sass stylesheets to that they may
8
+ # be `@imported`. This include path is used by every instance of
9
+ # {Sass::Embedded}. They are lower-precedence than any include paths passed
10
+ # in via the `:include_paths` option.
11
+ #
12
+ # If the `SASS_PATH` environment variable is set,
13
+ # the initial value of `include_paths` will be initialized based on that.
14
+ # The variable should be a colon-separated list of path names
15
+ # (semicolon-separated on Windows).
16
+ #
17
+ # @example
18
+ # Sass.include_paths << File.dirname(__FILE__) + '/sass'
19
+ # @return [Array<String, Pathname>]
20
+ def include_paths
21
+ @include_paths ||= if ENV['SASS_PATH']
22
+ ENV['SASS_PATH'].split(File::PATH_SEPARATOR)
23
+ else
24
+ []
25
+ end
26
+ end
27
+
28
+ def info
29
+ embedded.info
30
+ end
31
+
32
+ # The global render methods. This method automatically instantiates a
33
+ # global {Sass::Embedded} instance when invoked the first time and call
34
+ # `:render` method on the instance thereafter. The global {Sass::Embedded}
35
+ # is automatically closed via {Kernel.at_exit}.
36
+ # @example
37
+ # Sass.render(options)
38
+ # @return [Hash]
39
+ def render(**kwargs)
40
+ embedded.render(**kwargs)
41
+ end
42
+
43
+ private
44
+
45
+ def embedded
46
+ return @embedded if defined?(@embedded) && !@embedded.closed?
26
47
 
27
- # The global render methods. This method automatically instantiates a
28
- # global {Sass::Embedded} instance when invoked the first time and call
29
- # `:render` method on the instance thereafter. The global {Sass::Embedded}
30
- # is automatically closed via {Kernel.at_exit}.
31
- # @example
32
- # Sass.render(options)
33
- # @return [Hash]
34
- def self.render(**kwargs)
35
- unless defined? @embedded
36
48
  @embedded = Sass::Embedded.new
37
- at_exit do
38
- @embedded.close
39
- end
40
49
  end
41
- @embedded.render(**kwargs)
42
50
  end
43
51
  end
44
52
 
@@ -47,4 +55,5 @@ require_relative 'sass/error'
47
55
  require_relative 'sass/platform'
48
56
  require_relative 'sass/util'
49
57
  require_relative 'sass/transport'
58
+ require_relative 'sass/context'
50
59
  require_relative 'sass/embedded'
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ # An abstract context for maintaining state and observing transport
5
+ class Context
6
+ def initialize(transport, id)
7
+ raise NotImplementedError if instance_of? Context
8
+
9
+ @transport = transport
10
+ @id = id
11
+ @mutex = Mutex.new
12
+ @condition_variable = ConditionVariable.new
13
+ @response = nil
14
+ @error = nil
15
+ @transport.add_observer self
16
+ end
17
+
18
+ def fetch
19
+ @mutex.synchronize do
20
+ @condition_variable.wait(@mutex) if @error.nil? && @response.nil?
21
+ end
22
+
23
+ raise @error unless @error.nil?
24
+
25
+ @response
26
+ end
27
+
28
+ def update(error, message)
29
+ @transport.delete_observer self
30
+ @mutex.synchronize do
31
+ @error = error
32
+ @response = message
33
+ @condition_variable.broadcast
34
+ end
35
+ end
36
+ end
37
+ end
data/lib/sass/embedded.rb CHANGED
@@ -13,9 +13,7 @@ module Sass
13
13
  end
14
14
 
15
15
  def info
16
- @transport.send EmbeddedProtocol::InboundMessage::VersionRequest.new(
17
- id: next_id
18
- )
16
+ @info ||= InfoContext.new(@transport, next_id).fetch
19
17
  end
20
18
 
21
19
  def render(data: nil,
@@ -42,44 +40,24 @@ module Sass
42
40
  indent_width = parse_indent_width(indent_width)
43
41
  linefeed = parse_linefeed(linefeed)
44
42
 
45
- compilation_id = next_id
46
-
47
- renderer = Renderer.new(
48
- data: data,
49
- file: file,
50
- indented_syntax: indented_syntax,
51
- include_paths: include_paths,
52
- output_style: output_style,
53
- source_map: source_map,
54
- out_file: out_file,
55
- functions: functions,
56
- importer: importer
57
- )
58
-
59
- response = @transport.send renderer.compile_request(compilation_id), compilation_id
60
-
61
- loop do
62
- case response
63
- when EmbeddedProtocol::OutboundMessage::CompileResponse
64
- break
65
- when EmbeddedProtocol::OutboundMessage::CanonicalizeRequest
66
- response = @transport.send renderer.canonicalize_response(response), compilation_id
67
- when EmbeddedProtocol::OutboundMessage::ImportRequest
68
- response = @transport.send renderer.import_response(response), compilation_id
69
- when EmbeddedProtocol::OutboundMessage::FunctionCallRequest
70
- response = @transport.send renderer.function_call_response(response), compilation_id
71
- when EmbeddedProtocol::ProtocolError
72
- raise ProtocolError, response.message
73
- else
74
- raise ProtocolError, "Unexpected packet received: #{response}"
75
- end
76
- end
43
+ response = RenderContext.new(@transport, next_id,
44
+ data: data,
45
+ file: file,
46
+ indented_syntax: indented_syntax,
47
+ include_paths: include_paths,
48
+ output_style: output_style,
49
+ source_map: source_map,
50
+ out_file: out_file,
51
+ functions: functions,
52
+ importer: importer).fetch
77
53
 
78
54
  if response.failure
79
55
  raise RenderError.new(
80
56
  response.failure.message,
81
57
  response.failure.formatted,
82
- if response.failure.span&.url == ''
58
+ if response.failure.span.nil?
59
+ nil
60
+ elsif response.failure.span.url == ''
83
61
  'stdin'
84
62
  else
85
63
  Util.path(response.failure.span.url)
@@ -122,7 +100,10 @@ module Sass
122
100
 
123
101
  def close
124
102
  @transport.close
125
- nil
103
+ end
104
+
105
+ def closed?
106
+ @transport.closed?
126
107
  end
127
108
 
128
109
  private
@@ -239,9 +220,39 @@ module Sass
239
220
  end
240
221
  end
241
222
 
242
- # Helper class that maintains render state
243
- class Renderer
244
- def initialize(data:,
223
+ # InfoContext
224
+ class InfoContext < Context
225
+ def initialize(transport, id)
226
+ super(transport, id)
227
+ @transport.send EmbeddedProtocol::InboundMessage::VersionRequest.new(id: @id)
228
+ end
229
+
230
+ def update(error, message)
231
+ raise error unless error.nil?
232
+
233
+ response = message[message.message.to_s]
234
+
235
+ case response
236
+ when EmbeddedProtocol::ProtocolError
237
+ raise ProtocolError, response.message
238
+ when EmbeddedProtocol::OutboundMessage::VersionResponse
239
+ return unless response.id == @id
240
+
241
+ Thread.new do
242
+ super(nil, response)
243
+ end
244
+ end
245
+ rescue StandardError => e
246
+ Thread.new do
247
+ super(e, nil)
248
+ end
249
+ end
250
+ end
251
+
252
+ # RenderContext
253
+ class RenderContext < Context
254
+ def initialize(transport, id,
255
+ data:,
245
256
  file:,
246
257
  indented_syntax:,
247
258
  include_paths:,
@@ -252,6 +263,8 @@ module Sass
252
263
  importer:)
253
264
  raise ArgumentError, 'either data or file must be set' if file.nil? && data.nil?
254
265
 
266
+ super(transport, id)
267
+
255
268
  @data = data
256
269
  @file = file
257
270
  @indented_syntax = indented_syntax
@@ -265,11 +278,58 @@ module Sass
265
278
  end
266
279
  @importer = importer
267
280
  @import_responses = {}
281
+
282
+ @transport.send compile_request
283
+ end
284
+
285
+ def update(error, message)
286
+ raise error unless error.nil?
287
+
288
+ response = message[message.message.to_s]
289
+
290
+ case response
291
+ when EmbeddedProtocol::ProtocolError
292
+ raise ProtocolError, response.message
293
+ when EmbeddedProtocol::OutboundMessage::CompileResponse
294
+ return unless response.id == @id
295
+
296
+ Thread.new do
297
+ super(nil, response)
298
+ end
299
+ when EmbeddedProtocol::OutboundMessage::LogEvent
300
+ # not implemented yet
301
+ when EmbeddedProtocol::OutboundMessage::CanonicalizeRequest
302
+ return unless response['compilation_id'] == @id
303
+
304
+ Thread.new do
305
+ @transport.send canonicalize_response(response)
306
+ end
307
+ when EmbeddedProtocol::OutboundMessage::ImportRequest
308
+ return unless response['compilation_id'] == @id
309
+
310
+ Thread.new do
311
+ @transport.send import_response(response)
312
+ end
313
+ when EmbeddedProtocol::OutboundMessage::FileImportRequest
314
+ raise NotImplementedError, 'FileImportRequest is not implemented'
315
+ when EmbeddedProtocol::OutboundMessage::FunctionCallRequest
316
+ return unless response['compilation_id'] == @id
317
+
318
+ Thread.new do
319
+ @transport.send function_call_response(response)
320
+ end
321
+ end
322
+ rescue StandardError => e
323
+ Thread.new do
324
+ super(e, nil)
325
+ end
268
326
  end
269
327
 
270
- def compile_request(id)
328
+ private
329
+
330
+ def compile_request
271
331
  EmbeddedProtocol::InboundMessage::CompileRequest.new(
272
- id: id,
332
+ id: @id,
273
333
  string: string,
274
334
  path: path,
275
335
  style: style,
@@ -359,8 +419,6 @@ module Sass
359
419
  )
360
420
  end
361
421
 
362
- private
363
-
364
422
  def syntax
365
423
  if @indented_syntax == true
366
424
  EmbeddedProtocol::Syntax::INDENTED
@@ -25,37 +25,16 @@ module Sass
25
25
  receive
26
26
  end
27
27
 
28
- def send(req, id)
29
- mutex = Mutex.new
30
- resource = ConditionVariable.new
31
-
32
- req_kind = req.class.name.split('::').last.gsub(/\B(?=[A-Z])/, '_').downcase
33
-
34
- message = EmbeddedProtocol::InboundMessage.new(req_kind => req)
35
-
36
- error = nil
37
- res = nil
38
-
28
+ def add_observer(*args)
39
29
  @observerable_semaphore.synchronize do
40
- MessageObserver.new self, id do |e, r|
41
- mutex.synchronize do
42
- error = e
43
- res = r
44
-
45
- resource.signal
46
- end
47
- end
48
- end
49
-
50
- mutex.synchronize do
51
- write message.to_proto
52
-
53
- resource.wait(mutex)
30
+ super(*args)
54
31
  end
32
+ end
55
33
 
56
- raise error if error
57
-
58
- res
34
+ def send(req)
35
+ req_kind = req.class.name.split('::').last.gsub(/\B(?=[A-Z])/, '_').downcase
36
+ message = EmbeddedProtocol::InboundMessage.new(req_kind => req)
37
+ write message.to_proto
59
38
  end
60
39
 
61
40
  def close
@@ -66,6 +45,10 @@ module Sass
66
45
  nil
67
46
  end
68
47
 
48
+ def closed?
49
+ @stdin.closed?
50
+ end
51
+
69
52
  private
70
53
 
71
54
  def receive
@@ -78,10 +61,11 @@ module Sass
78
61
  bits += 7
79
62
  break if byte <= 0x7f
80
63
  end
81
- changed
82
64
  payload = @stdout.read length
65
+ message = EmbeddedProtocol::OutboundMessage.decode payload
83
66
  @observerable_semaphore.synchronize do
84
- notify_observers nil, EmbeddedProtocol::OutboundMessage.decode(payload)
67
+ changed
68
+ notify_observers nil, message
85
69
  end
86
70
  rescue Interrupt
87
71
  break
@@ -119,32 +103,5 @@ module Sass
119
103
  @stdin.write payload
120
104
  end
121
105
  end
122
-
123
- # The observer used to listen on messages from stdout, check if id
124
- # matches the given request id, and yield back to the given block.
125
- class MessageObserver
126
- def initialize(obs, id, &block)
127
- @obs = obs
128
- @id = id
129
- @block = block
130
- @obs.add_observer self
131
- end
132
-
133
- def update(error, message)
134
- if error
135
- @obs.delete_observer self
136
- @block.call error, nil
137
- elsif message.error&.id == Transport::PROTOCOL_ERROR_ID
138
- @obs.delete_observer self
139
- @block.call ProtocolError.new(message.error.message), nil
140
- else
141
- res = message[message.message.to_s]
142
- if (res['compilation_id'] || res['id']) == @id
143
- @obs.delete_observer self
144
- @block.call error, res
145
- end
146
- end
147
- end
148
- end
149
106
  end
150
107
  end
data/lib/sass/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sass
4
- VERSION = '0.4.0'
4
+ VERSION = '0.4.1'
5
5
  end
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
20
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
21
 
22
- spec.required_ruby_version = '>= 2.6'
22
+ spec.required_ruby_version = '>= 2.6.0'
23
23
 
24
24
  spec.require_paths = ['lib']
25
25
 
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.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - なつき
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-27 00:00:00.000000000 Z
11
+ date: 2021-05-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-protobuf
@@ -155,6 +155,7 @@ files:
155
155
  - ext/Makefile
156
156
  - ext/extconf.rb
157
157
  - lib/sass.rb
158
+ - lib/sass/context.rb
158
159
  - lib/sass/embedded.rb
159
160
  - lib/sass/error.rb
160
161
  - lib/sass/platform.rb
@@ -185,7 +186,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
185
186
  requirements:
186
187
  - - ">="
187
188
  - !ruby/object:Gem::Version
188
- version: '2.6'
189
+ version: 2.6.0
189
190
  required_rubygems_version: !ruby/object:Gem::Requirement
190
191
  requirements:
191
192
  - - ">="