sass-embedded 0.1.2 → 0.1.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 +4 -4
- data/.github/workflows/build.yml +0 -3
- data/Gemfile +2 -0
- data/Rakefile +3 -1
- data/ext/sass_embedded/extconf.rb +55 -62
- data/lib/sass.rb +13 -8
- data/lib/sass/embedded/compiler.rb +95 -107
- data/lib/sass/embedded/transport.rb +55 -62
- data/lib/sass/error.rb +5 -2
- data/lib/sass/platform.rb +17 -20
- data/lib/sass/util.rb +4 -4
- data/lib/sass/version.rb +1 -2
- data/sass-embedded.gemspec +18 -19
- data/test/compiler_test.rb +151 -153
- data/test/custom_importer_test.rb +95 -93
- data/test/error_test.rb +13 -15
- data/test/functions_test.rb +193 -177
- data/test/output_style_test.rb +44 -44
- data/test/sass_test.rb +22 -0
- data/test/test_helper.rb +5 -5
- metadata +17 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c42f58b6f4f3200d3033fd59e65e7cd33132731ab4520bafb2a375cf55577ec
|
4
|
+
data.tar.gz: 2da13b64dab78a0b3fccd9a90cfcc6bd5affcd09dfe0b978aed53b69b2afa51e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d484872bd432f0092e67f699b18af1e242c982ff0e2019f9d23340593744ca58a015f5d63c76ae83d0a29e05ed362a2015f8f55bdbe472da67488e99c1cdaa8f
|
7
|
+
data.tar.gz: bd452474519dabcd9d793205d8f0dcc64482a5313d48d9eda4464f0a5d6ed8b9d6a34ea1c57e4a8f178beafb008b080481fd6059ab2f3ad53494e2acd272527b
|
data/.github/workflows/build.yml
CHANGED
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'bundler/gem_tasks'
|
2
4
|
|
3
5
|
task default: :test
|
@@ -10,5 +12,5 @@ end
|
|
10
12
|
desc 'Run all tests'
|
11
13
|
task :test do
|
12
14
|
$LOAD_PATH.unshift('lib', 'test')
|
13
|
-
Dir.glob('./test/**/*_test.rb') { |f| require f }
|
15
|
+
Dir.glob('./test/**/*_test.rb').sort.each { |f| require f }
|
14
16
|
end
|
@@ -1,131 +1,124 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require_relative
|
4
|
+
require 'mkmf'
|
5
|
+
require 'json'
|
6
|
+
require 'open-uri'
|
7
|
+
require_relative '../../lib/sass/platform'
|
7
8
|
|
8
|
-
def api
|
9
|
+
def api(url)
|
9
10
|
headers = {}
|
10
|
-
headers[
|
11
|
-
URI.open(
|
11
|
+
headers['Authorization'] = "token #{ENV['GITHUB_TOKEN']}" if ENV['GITHUB_TOKEN']
|
12
|
+
URI.parse(url).open(headers) do |file|
|
12
13
|
JSON.parse file.read
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
16
|
-
def download
|
17
|
-
URI.
|
18
|
-
File.open(File.absolute_path(File.basename(url), __dir__),
|
17
|
+
def download(url)
|
18
|
+
URI.parse(url).open do |source|
|
19
|
+
File.open(File.absolute_path(File.basename(url), __dir__), 'wb') do |destination|
|
19
20
|
destination.write source.read
|
20
21
|
end
|
21
22
|
end
|
23
|
+
rescue StandardError
|
24
|
+
raise "Failed to download: #{url}"
|
22
25
|
end
|
23
26
|
|
24
27
|
def download_sass_embedded
|
25
|
-
repo =
|
28
|
+
repo = 'sass/dart-sass-embedded'
|
26
29
|
|
27
30
|
release = api("https://api.github.com/repos/#{repo}/releases")[0]['tag_name']
|
28
31
|
|
29
32
|
os = case Sass::Platform::OS
|
30
|
-
when
|
31
|
-
|
32
|
-
when
|
33
|
-
|
34
|
-
when
|
35
|
-
|
33
|
+
when 'darwin'
|
34
|
+
'macos'
|
35
|
+
when 'linux'
|
36
|
+
'linux'
|
37
|
+
when 'windows'
|
38
|
+
'windows'
|
36
39
|
else
|
37
40
|
raise "Unsupported OS: #{Sass::Platform::OS}"
|
38
41
|
end
|
39
42
|
|
40
43
|
arch = case Sass::Platform::ARCH
|
41
|
-
when
|
42
|
-
|
43
|
-
when
|
44
|
-
|
44
|
+
when 'x86_64'
|
45
|
+
'x64'
|
46
|
+
when 'i386'
|
47
|
+
'ia32'
|
45
48
|
else
|
46
49
|
raise "Unsupported Arch: #{Sass::Platform::ARCH}"
|
47
50
|
end
|
48
51
|
|
49
52
|
ext = case os
|
50
|
-
when
|
51
|
-
|
53
|
+
when 'windows'
|
54
|
+
'zip'
|
52
55
|
else
|
53
|
-
|
56
|
+
'tar.gz'
|
54
57
|
end
|
55
58
|
|
56
59
|
url = "https://github.com/#{repo}/releases/download/#{release}/sass_embedded-#{release}-#{os}-#{arch}.#{ext}"
|
57
|
-
|
58
|
-
begin
|
59
|
-
download url
|
60
|
-
rescue
|
61
|
-
raise "Failed to download: #{url}"
|
62
|
-
end
|
60
|
+
download url
|
63
61
|
end
|
64
62
|
|
65
63
|
def download_protoc
|
66
|
-
repo =
|
64
|
+
repo = 'protocolbuffers/protobuf'
|
67
65
|
|
68
|
-
tag = URI.
|
66
|
+
tag = URI.parse("https://github.com/#{repo}/releases/latest").open do |file|
|
69
67
|
File.basename file.base_uri.to_s
|
70
|
-
|
68
|
+
end
|
71
69
|
|
72
70
|
release = tag[1..-1]
|
73
71
|
|
74
72
|
os = case Sass::Platform::OS
|
75
|
-
when
|
76
|
-
|
77
|
-
when
|
78
|
-
|
79
|
-
when
|
80
|
-
|
73
|
+
when 'darwin'
|
74
|
+
'osx'
|
75
|
+
when 'linux'
|
76
|
+
'linux'
|
77
|
+
when 'windows'
|
78
|
+
'win'
|
81
79
|
else
|
82
80
|
raise "Unsupported OS: #{Sass::Platform::OS}"
|
83
81
|
end
|
84
82
|
|
85
83
|
arch = case Sass::Platform::ARCH
|
86
|
-
when
|
87
|
-
|
88
|
-
when
|
89
|
-
|
90
|
-
when
|
91
|
-
|
92
|
-
when
|
93
|
-
|
94
|
-
when
|
95
|
-
|
84
|
+
when 'aarch64'
|
85
|
+
'aarch_64'
|
86
|
+
when 'sparcv9'
|
87
|
+
's390'
|
88
|
+
when 'i386'
|
89
|
+
'x86_32'
|
90
|
+
when 'x86_64'
|
91
|
+
'x86_64'
|
92
|
+
when 'powerpc64'
|
93
|
+
'ppcle_64'
|
96
94
|
else
|
97
95
|
raise "Unsupported Arch: #{Sass::Platform::ARCH}"
|
98
96
|
end
|
99
97
|
|
100
98
|
os_arch = case os
|
101
|
-
when
|
99
|
+
when 'win'
|
102
100
|
os + arch.split('_').last
|
103
101
|
else
|
104
|
-
os
|
102
|
+
"#{os}-#{arch}"
|
105
103
|
end
|
106
104
|
|
107
|
-
ext =
|
105
|
+
ext = 'zip'
|
108
106
|
|
109
107
|
url = "https://github.com/#{repo}/releases/download/#{tag}/protoc-#{release}-#{os_arch}.#{ext}"
|
110
|
-
|
111
|
-
begin
|
112
|
-
download url
|
113
|
-
rescue
|
114
|
-
raise "Failed to download: #{url}"
|
115
|
-
end
|
108
|
+
download url
|
116
109
|
end
|
117
110
|
|
118
111
|
def download_embedded_sass_proto
|
119
|
-
url =
|
112
|
+
url = 'https://raw.githubusercontent.com/sass/embedded-protocol/HEAD/embedded_sass.proto'
|
120
113
|
download url
|
121
114
|
end
|
122
115
|
|
123
|
-
system(
|
116
|
+
system('make', '-C', __dir__, 'distclean')
|
124
117
|
download_sass_embedded
|
125
118
|
download_protoc
|
126
119
|
download_embedded_sass_proto
|
127
|
-
system(
|
120
|
+
system('make', '-C', __dir__, 'install')
|
128
121
|
|
129
|
-
File.open(File.absolute_path("sass_embedded.#{RbConfig::CONFIG['DLEXT']}", __dir__),
|
122
|
+
File.open(File.absolute_path("sass_embedded.#{RbConfig::CONFIG['DLEXT']}", __dir__), 'w') {}
|
130
123
|
|
131
124
|
$makefile_created = true
|
data/lib/sass.rb
CHANGED
@@ -23,15 +23,20 @@ module Sass
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
def self.render
|
27
|
-
@compiler
|
26
|
+
def self.render(options)
|
27
|
+
unless defined? @compiler
|
28
|
+
@compiler = Sass::Embedded::Compiler.new
|
29
|
+
at_exit do
|
30
|
+
@compiler.close
|
31
|
+
end
|
32
|
+
end
|
28
33
|
@compiler.render options
|
29
34
|
end
|
30
35
|
end
|
31
36
|
|
32
|
-
require_relative
|
33
|
-
require_relative
|
34
|
-
require_relative
|
35
|
-
require_relative
|
36
|
-
require_relative
|
37
|
-
require_relative
|
37
|
+
require_relative 'sass/version'
|
38
|
+
require_relative 'sass/error'
|
39
|
+
require_relative 'sass/platform'
|
40
|
+
require_relative 'sass/util'
|
41
|
+
require_relative 'sass/embedded/transport'
|
42
|
+
require_relative 'sass/embedded/compiler'
|
@@ -3,39 +3,24 @@
|
|
3
3
|
module Sass
|
4
4
|
module Embedded
|
5
5
|
class Compiler
|
6
|
-
|
7
6
|
def initialize
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
else
|
12
|
-
@@transport.close
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
@@transport = Transport.new
|
17
|
-
@@pwd = Dir.pwd
|
18
|
-
|
19
|
-
@@id_semaphore = Mutex.new
|
20
|
-
@@id = 0
|
7
|
+
@transport = Transport.new
|
8
|
+
@id_semaphore = Mutex.new
|
9
|
+
@id = 0
|
21
10
|
end
|
22
11
|
|
23
|
-
def render
|
12
|
+
def render(options)
|
24
13
|
start = Sass::Util.now
|
25
14
|
|
26
|
-
if options[:file].nil? && options[:data].nil?
|
27
|
-
raise Sass::NotRenderedError.new 'Either :data or :file must be set.'
|
28
|
-
end
|
15
|
+
raise Sass::NotRenderedError, 'Either :data or :file must be set.' if options[:file].nil? && options[:data].nil?
|
29
16
|
|
30
|
-
if options[:
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
:syntax => options[:indented_syntax] == true ? Sass::EmbeddedProtocol::Syntax::INDENTED : Sass::EmbeddedProtocol::Syntax::SCSS
|
38
|
-
) : nil
|
17
|
+
string = if options[:data]
|
18
|
+
Sass::EmbeddedProtocol::InboundMessage::CompileRequest::StringInput.new(
|
19
|
+
source: options[:data],
|
20
|
+
url: options[:file] ? Sass::Util.file_uri(options[:file]) : 'stdin',
|
21
|
+
syntax: options[:indented_syntax] == true ? Sass::EmbeddedProtocol::Syntax::INDENTED : Sass::EmbeddedProtocol::Syntax::SCSS
|
22
|
+
)
|
23
|
+
end
|
39
24
|
|
40
25
|
path = options[:data] ? nil : options[:file]
|
41
26
|
|
@@ -45,49 +30,55 @@ module Sass
|
|
45
30
|
when :compressed
|
46
31
|
Sass::EmbeddedProtocol::OutputStyle::COMPRESSED
|
47
32
|
when :nested, :compact
|
48
|
-
raise Sass::UnsupportedValue
|
33
|
+
raise Sass::UnsupportedValue, "#{options[:output_style]} is not a supported :output_style"
|
49
34
|
else
|
50
|
-
raise Sass::InvalidStyleError
|
35
|
+
raise Sass::InvalidStyleError, "#{options[:output_style]} is not a valid :output_style"
|
51
36
|
end
|
52
37
|
|
53
|
-
source_map = options[:source_map].is_a?
|
38
|
+
source_map = options[:source_map].is_a?(String) || (options[:source_map] == true && !options[:out_file].nil?)
|
54
39
|
|
55
40
|
# 1. Loading a file relative to the file in which the @use or @import appeared.
|
56
41
|
# 2. Each custom importer.
|
57
42
|
# 3. Loading a file relative to the current working directory.
|
58
43
|
# 4. Each load path in includePaths
|
59
44
|
# 5. Each load path specified in the SASS_PATH environment variable, which should be semicolon-separated on Windows and colon-separated elsewhere.
|
60
|
-
importers = (options[:importer]
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
45
|
+
importers = (if options[:importer]
|
46
|
+
[
|
47
|
+
Sass::EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new(importer_id: 0)
|
48
|
+
]
|
49
|
+
else
|
50
|
+
[]
|
51
|
+
end).concat(
|
52
|
+
(options[:include_paths] || []).concat(Sass.include_paths)
|
53
|
+
.map do |include_path|
|
54
|
+
Sass::EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new(
|
55
|
+
path: File.absolute_path(include_path)
|
56
|
+
)
|
57
|
+
end
|
58
|
+
)
|
68
59
|
|
69
60
|
signatures = []
|
70
61
|
functions = {}
|
71
|
-
options[:functions]&.each
|
62
|
+
options[:functions]&.each do |signature, function|
|
72
63
|
signatures.push signature
|
73
64
|
functions[signature.to_s.split('(')[0].chomp] = function
|
74
|
-
|
65
|
+
end
|
75
66
|
|
76
67
|
compilation_id = next_id
|
77
68
|
|
78
69
|
compile_request = Sass::EmbeddedProtocol::InboundMessage::CompileRequest.new(
|
79
|
-
:
|
80
|
-
:
|
81
|
-
:
|
82
|
-
:
|
83
|
-
:
|
84
|
-
:
|
85
|
-
:
|
86
|
-
:
|
87
|
-
:
|
70
|
+
id: compilation_id,
|
71
|
+
string: string,
|
72
|
+
path: path,
|
73
|
+
style: style,
|
74
|
+
source_map: source_map,
|
75
|
+
importers: importers,
|
76
|
+
global_functions: options[:functions] ? signatures : [],
|
77
|
+
alert_color: true,
|
78
|
+
alert_ascii: true
|
88
79
|
)
|
89
80
|
|
90
|
-
response =
|
81
|
+
response = @transport.send compile_request, compilation_id
|
91
82
|
|
92
83
|
file = options[:file] || 'stdin'
|
93
84
|
canonicalizations = {}
|
@@ -100,95 +91,95 @@ module Sass
|
|
100
91
|
when Sass::EmbeddedProtocol::OutboundMessage::CanonicalizeRequest
|
101
92
|
url = Sass::Util.file_uri(File.absolute_path(response.url, File.dirname(file)))
|
102
93
|
|
103
|
-
if canonicalizations.
|
94
|
+
if canonicalizations.key? url
|
104
95
|
canonicalizations[url].id = response.id
|
105
96
|
else
|
106
97
|
resolved = nil
|
107
|
-
options[:importer].each
|
98
|
+
options[:importer].each do |importer|
|
108
99
|
begin
|
109
100
|
resolved = importer.call response.url, file
|
110
|
-
rescue
|
111
|
-
resolved =
|
101
|
+
rescue StandardError => e
|
102
|
+
resolved = e
|
112
103
|
end
|
113
104
|
break if resolved
|
114
|
-
|
105
|
+
end
|
115
106
|
if resolved.nil?
|
116
107
|
canonicalizations[url] = Sass::EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
|
117
|
-
:
|
118
|
-
:
|
108
|
+
id: response.id,
|
109
|
+
url: url
|
119
110
|
)
|
120
|
-
elsif resolved.is_a?
|
111
|
+
elsif resolved.is_a? StandardError
|
121
112
|
canonicalizations[url] = Sass::EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
|
122
|
-
:
|
123
|
-
:
|
113
|
+
id: response.id,
|
114
|
+
error: resolved.message
|
124
115
|
)
|
125
|
-
elsif resolved.
|
116
|
+
elsif resolved.key? :contents
|
126
117
|
canonicalizations[url] = Sass::EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
|
127
|
-
:
|
128
|
-
:
|
118
|
+
id: response.id,
|
119
|
+
url: url
|
129
120
|
)
|
130
121
|
imports[url] = Sass::EmbeddedProtocol::InboundMessage::ImportResponse.new(
|
131
|
-
:
|
132
|
-
:
|
133
|
-
:
|
134
|
-
:
|
135
|
-
:
|
122
|
+
id: response.id,
|
123
|
+
success: Sass::EmbeddedProtocol::InboundMessage::ImportResponse::ImportSuccess.new(
|
124
|
+
contents: resolved[:contents],
|
125
|
+
syntax: Sass::EmbeddedProtocol::Syntax::SCSS,
|
126
|
+
source_map_url: nil
|
136
127
|
)
|
137
128
|
)
|
138
|
-
elsif resolved.
|
129
|
+
elsif resolved.key? :file
|
139
130
|
canonicalized_url = Sass::Util.file_uri(resolved[:file])
|
140
131
|
canonicalizations[url] = Sass::EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
|
141
|
-
:
|
142
|
-
:
|
132
|
+
id: response.id,
|
133
|
+
url: canonicalized_url
|
143
134
|
)
|
144
135
|
imports[canonicalized_url] = Sass::EmbeddedProtocol::InboundMessage::ImportResponse.new(
|
145
|
-
:
|
146
|
-
:
|
147
|
-
:
|
148
|
-
:
|
149
|
-
:
|
136
|
+
id: response.id,
|
137
|
+
success: Sass::EmbeddedProtocol::InboundMessage::ImportResponse::ImportSuccess.new(
|
138
|
+
contents: File.read(resolved[:file]),
|
139
|
+
syntax: Sass::EmbeddedProtocol::Syntax::SCSS,
|
140
|
+
source_map_url: nil
|
150
141
|
)
|
151
142
|
)
|
152
143
|
else
|
153
144
|
canonicalizations[url] = Sass::EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
|
154
|
-
:
|
155
|
-
:
|
145
|
+
id: response.id,
|
146
|
+
error: "Unexpected value returned from importer: #{resolved}"
|
156
147
|
)
|
157
148
|
end
|
158
149
|
end
|
159
150
|
|
160
|
-
response =
|
151
|
+
response = @transport.send canonicalizations[url], compilation_id
|
161
152
|
when Sass::EmbeddedProtocol::OutboundMessage::ImportRequest
|
162
153
|
url = response.url
|
163
154
|
|
164
|
-
if imports.
|
155
|
+
if imports.key? url
|
165
156
|
imports[url].id = response.id
|
166
157
|
else
|
167
158
|
imports[url] = Sass::EmbeddedProtocol::InboundMessage::ImportResponse.new(
|
168
|
-
:
|
169
|
-
:
|
159
|
+
id: response.id,
|
160
|
+
error: "Failed to import: #{url}"
|
170
161
|
)
|
171
162
|
end
|
172
163
|
|
173
|
-
response =
|
164
|
+
response = @transport.send imports[url], compilation_id
|
174
165
|
when Sass::EmbeddedProtocol::OutboundMessage::FunctionCallRequest
|
175
166
|
begin
|
176
167
|
message = Sass::EmbeddedProtocol::InboundMessage::FunctionCallResponse.new(
|
177
|
-
:
|
178
|
-
:
|
168
|
+
id: response.id,
|
169
|
+
success: functions[response.name].call(*response.arguments)
|
179
170
|
)
|
180
|
-
rescue
|
171
|
+
rescue StandardError => e
|
181
172
|
message = Sass::EmbeddedProtocol::InboundMessage::FunctionCallResponse.new(
|
182
|
-
:
|
183
|
-
:
|
173
|
+
id: response.id,
|
174
|
+
error: e.message
|
184
175
|
)
|
185
176
|
end
|
186
177
|
|
187
|
-
response =
|
178
|
+
response = @transport.send message, compilation_id
|
188
179
|
when Sass::EmbeddedProtocol::ProtocolError
|
189
|
-
raise Sass::ProtocolError
|
180
|
+
raise Sass::ProtocolError, response.message
|
190
181
|
else
|
191
|
-
raise Sass::ProtocolError
|
182
|
+
raise Sass::ProtocolError, "Unexpected packet received: #{response}"
|
192
183
|
end
|
193
184
|
end
|
194
185
|
|
@@ -205,7 +196,7 @@ module Sass
|
|
205
196
|
|
206
197
|
finish = Sass::Util.now
|
207
198
|
|
208
|
-
|
199
|
+
{
|
209
200
|
css: response.success.css,
|
210
201
|
map: response.success.source_map,
|
211
202
|
stats: {
|
@@ -217,13 +208,17 @@ module Sass
|
|
217
208
|
}
|
218
209
|
end
|
219
210
|
|
211
|
+
def close
|
212
|
+
@transport.close
|
213
|
+
end
|
214
|
+
|
220
215
|
private
|
221
216
|
|
222
217
|
def info
|
223
|
-
version_response =
|
224
|
-
:
|
218
|
+
version_response = @transport.send Sass::EmbeddedProtocol::InboundMessage::VersionRequest.new(
|
219
|
+
id: next_id
|
225
220
|
)
|
226
|
-
|
221
|
+
{
|
227
222
|
compiler_version: version_response.compiler_version,
|
228
223
|
protocol_version: version_response.protocol_version,
|
229
224
|
implementation_name: version_response.implementation_name,
|
@@ -232,18 +227,11 @@ module Sass
|
|
232
227
|
end
|
233
228
|
|
234
229
|
def next_id
|
235
|
-
|
236
|
-
|
237
|
-
if
|
238
|
-
|
239
|
-
|
240
|
-
@@id
|
241
|
-
}
|
242
|
-
end
|
243
|
-
|
244
|
-
def restart
|
245
|
-
@@transport.close
|
246
|
-
@@transport = Transport.new
|
230
|
+
@id_semaphore.synchronize do
|
231
|
+
@id += 1
|
232
|
+
@id = 0 if @id == Transport::PROTOCOL_ERROR_ID
|
233
|
+
@id
|
234
|
+
end
|
247
235
|
end
|
248
236
|
end
|
249
237
|
end
|