sass-embedded 0.7.28 → 0.9.0

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 == Transport::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
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative 'sass'
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,27 +45,15 @@ 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?
53
+ def instance
54
+ return @instance if defined?(@instance) && !@instance.closed?
57
55
 
58
- @embedded = Sass::Embedded.new
56
+ @instance = Embedded.new
59
57
  end
60
58
  end
61
59
  end
62
-
63
- require_relative 'sass/version'
64
- require_relative 'sass/platform'
65
- require_relative 'sass/util'
66
- require_relative 'sass/struct'
67
- require_relative 'sass/result'
68
- require_relative 'sass/error'
69
- require_relative 'sass/transport'
70
- require_relative 'sass/observer'
71
- require_relative 'sass/info'
72
- require_relative 'sass/compile'
73
- 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.7.28
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - なつき
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-22 00:00:00.000000000 Z
11
+ date: 2021-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-protobuf
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: 0.15.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-performance
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 1.11.5
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 1.11.5
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: rubocop-rake
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -120,27 +134,31 @@ files:
120
134
  - LICENSE
121
135
  - README.md
122
136
  - ext/sass/Makefile
123
- - ext/sass/dependencies.rb
124
137
  - ext/sass/extconf.rb
125
138
  - ext/sass/unzip.vbs
139
+ - lib/sass-embedded.rb
126
140
  - lib/sass.rb
127
- - lib/sass/compile.rb
128
141
  - lib/sass/embedded.rb
129
- - lib/sass/error.rb
130
- - lib/sass/info.rb
131
- - lib/sass/observer.rb
132
- - lib/sass/platform.rb
133
- - lib/sass/result.rb
134
- - lib/sass/struct.rb
135
- - lib/sass/transport.rb
136
- - lib/sass/util.rb
137
- - 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/struct.rb
152
+ - lib/sass/embedded/util.rb
153
+ - lib/sass/embedded/version.rb
154
+ - lib/sass/embedded/version_context.rb
155
+ - lib/sass/embedded_protocol.rb
138
156
  homepage: https://github.com/ntkme/sass-embedded-host-ruby
139
157
  licenses:
140
158
  - MIT
141
159
  metadata:
142
- documentation_uri: https://www.rubydoc.info/gems/sass-embedded/0.7.28
143
- source_code_uri: https://github.com/ntkme/sass-embedded-host-ruby/tree/v0.7.28
160
+ documentation_uri: https://www.rubydoc.info/gems/sass-embedded/0.9.0
161
+ source_code_uri: https://github.com/ntkme/sass-embedded-host-ruby/tree/v0.9.0
144
162
  funding_uri: https://github.com/sponsors/ntkme
145
163
  post_install_message:
146
164
  rdoc_options: []
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Sass
4
- module Dependencies
5
- REQUIREMENTS = {
6
- 'protocolbuffers/protobuf' => '~> 3.18.0',
7
- 'sass/embedded-protocol' => '~> 1.0.0-beta.12',
8
- 'sass/dart-sass-embedded' => '~> 1.0.0-beta.11'
9
- }.freeze
10
- end
11
- end
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/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
data/lib/sass/result.rb DELETED
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Sass
4
- # The {RenderResult} of {Embedded#render}.
5
- class RenderResult
6
- include Struct
7
-
8
- attr_reader :css, :map, :stats
9
-
10
- def initialize(css, map, stats)
11
- @css = css
12
- @map = map
13
- @stats = stats
14
- end
15
- end
16
-
17
- # The {RenderResultStats} of {Embedded#render}.
18
- class RenderResultStats
19
- include Struct
20
-
21
- attr_reader :entry, :start, :end, :duration
22
-
23
- def initialize(entry, start, finish, duration)
24
- @entry = entry
25
- @start = start
26
- @end = finish
27
- @duration = duration
28
- end
29
- end
30
- end