sass-embedded 1.0.6 → 1.0.9

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: bb22fd222502bd171a92c0f112b0644dda7b3c6badf12c9f9aa9b079c0856681
4
- data.tar.gz: fd6f3666396b577de10d2c8403dd3bbdcf382b9d7e6a656d2da7ca6750ff0e38
3
+ metadata.gz: e66ada7e45e9d2645c9c11569f907001a4d8f9711df90f9cebe726e0a40d9539
4
+ data.tar.gz: aa2139021df463e31a2fa6f02d9515dd6b9553b57d73d38e831ad67ecb688275
5
5
  SHA512:
6
- metadata.gz: e75993c794dfde2f004cff309537562914b6cf5efcc9898f5b5b5b2e92c8cf5f616397ba363477768c36c2e42a1548c3f6897d2d28cdd4c4010489b744ff0626
7
- data.tar.gz: 1116525243f799d4fa7ac0fb52fe3f59f5a5d2c08256d347c88ff19a48eef714ce3e2ccc58e8b71b61ebb055b80322b84017df207b5b047a802b8dea585fd73c
6
+ metadata.gz: bc77ad8ef5cbd139360443308899212ce95fd4b3be3be31fbca1f331f7cc73e6bd5ad0f6f2bc853d486ca0a90bc1e3fdf043adbcb534060f17c2209a7eac9499
7
+ data.tar.gz: 61918d88ebfa21159851b0294d1366b2ff403c3168592dc70554c68810a777552ecb773849e790fd9f8bd1be1f2e4839732700b02a5faf7b4db448776c34b120
data/README.md CHANGED
@@ -15,11 +15,24 @@ gem install sass-embedded
15
15
 
16
16
  ## Usage
17
17
 
18
+ The Ruby API provides two entrypoints for compiling Sass to CSS.
19
+
20
+ - `Sass.compile` takes a path to a Sass file and return the result of compiling that file to CSS.
21
+
22
+ ``` ruby
23
+ require 'sass'
24
+
25
+ result = Sass.compile('style.scss')
26
+ puts result.css
27
+ ```
28
+
29
+ - `Sass.compile_string` takes a string that represents the contents of a Sass file and return the result of compiling that file to CSS.
30
+
18
31
  ``` ruby
19
32
  require 'sass'
20
33
 
21
- Sass.compile('style.scss')
22
- Sass.compile_string('h1 { font-size: 40px; }')
34
+ result = Sass.compile_string('h1 { font-size: 40px; }')
35
+ puts result.css
23
36
  ```
24
37
 
25
38
  ---
data/ext/sass/Rakefile ADDED
@@ -0,0 +1,245 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'open-uri'
5
+ require 'open3'
6
+ require 'rake/clean'
7
+
8
+ task default: %i[install clean]
9
+
10
+ task install: %w[sass_embedded embedded_sass_pb.rb]
11
+
12
+ CLEAN.include %w[protoc *.proto *.tar.gz *.zip]
13
+
14
+ CLOBBER.include %w[sass_embedded embedded_sass_pb.rb]
15
+
16
+ file 'protoc' do |t|
17
+ archive = fetch(ENV.fetch(t.name.upcase) { Configuration.default_protoc })
18
+ unzip archive, t.name
19
+ rm archive
20
+ end
21
+
22
+ file 'sass_embedded' do |t|
23
+ archive = fetch(ENV.fetch(t.name.upcase) { Configuration.default_sass_embedded })
24
+ if Gem.win_platform?
25
+ unzip archive
26
+ else
27
+ sh 'tar', '-vxzf', archive
28
+ end
29
+ rm archive
30
+ end
31
+
32
+ file 'embedded_sass.proto' => %w[sass_embedded] do |t|
33
+ fetch(ENV.fetch('sass_embedded_protocol'.upcase) { Configuration.default_sass_embedded_protocol }, t.name)
34
+ end
35
+
36
+ rule '_pb.rb' => %w[.proto protoc] do |t|
37
+ sh './protoc/bin/protoc', '--ruby_out=.', t.source
38
+ end
39
+
40
+ # This is a FileUtils extension that defines several additional commands to be
41
+ # added to the FileUtils utility functions.
42
+ module FileUtils
43
+ def unzip(archive, dest = '.')
44
+ if Gem.win_platform?
45
+ sh 'powershell', '-File', 'unzip.ps1', '-Archive', archive, '-DestinationPath', dest
46
+ else
47
+ sh 'unzip', '-od', dest, archive
48
+ end
49
+ end
50
+
51
+ def fetch(uri_or_path, dest = nil)
52
+ begin
53
+ uri = URI.parse(uri_or_path)
54
+ path = URI::DEFAULT_PARSER.unescape(uri.path)
55
+ if uri.instance_of?(URI::File) || uri.instance_of?(URI::Generic)
56
+ path = path.delete_prefix('/') if Gem.win_platform? && !File.file?(path)
57
+ raise unless File.file?(path)
58
+ end
59
+ rescue StandardError
60
+ raise unless File.file?(uri_or_path)
61
+
62
+ uri = nil
63
+ path = uri_or_path
64
+ end
65
+
66
+ dest = File.basename(path) if dest.nil?
67
+
68
+ if uri.nil? || uri.instance_of?(URI::File) || uri.instance_of?(URI::Generic)
69
+ cp path, dest
70
+ elsif uri.respond_to?(:open)
71
+ Rake.rake_output_message "curl -fsSLo #{dest} -- #{uri}" if Rake::FileUtilsExt.verbose_flag
72
+ unless Rake::FileUtilsExt.nowrite_flag
73
+ uri.open do |stream|
74
+ File.binwrite(dest, stream.read)
75
+ end
76
+ end
77
+ else
78
+ raise
79
+ end
80
+
81
+ dest
82
+ rescue StandardError
83
+ raise "Failed to fetch #{uri_or_path}"
84
+ end
85
+ end
86
+
87
+ # The {Configuration} module.
88
+ module Configuration
89
+ module Platform
90
+ OS = case RbConfig::CONFIG['host_os'].downcase
91
+ when /linux/
92
+ 'linux'
93
+ when /darwin/
94
+ 'darwin'
95
+ when /freebsd/
96
+ 'freebsd'
97
+ when /netbsd/
98
+ 'netbsd'
99
+ when /openbsd/
100
+ 'openbsd'
101
+ when /dragonfly/
102
+ 'dragonflybsd'
103
+ when /sunos|solaris/
104
+ 'solaris'
105
+ when *Gem::WIN_PATTERNS
106
+ 'windows'
107
+ else
108
+ RbConfig::CONFIG['host_os'].downcase
109
+ end
110
+
111
+ OSVERSION = RbConfig::CONFIG['host_os'].gsub(/[^\d]/, '').to_i
112
+
113
+ CPU = RbConfig::CONFIG['host_cpu']
114
+
115
+ ARCH = case CPU.downcase
116
+ when /amd64|x86_64|x64/
117
+ 'x86_64'
118
+ when /i\d86|x86|i86pc/
119
+ 'i386'
120
+ when /ppc64|powerpc64/
121
+ 'powerpc64'
122
+ when /ppc|powerpc/
123
+ 'powerpc'
124
+ when /sparcv9|sparc64/
125
+ 'sparcv9'
126
+ when /arm64|aarch64/ # MacOS calls it "arm64", other operating systems "aarch64"
127
+ 'aarch64'
128
+ when /^arm/
129
+ if OS == 'darwin' # Ruby before 3.0 reports "arm" instead of "arm64" as host_cpu on darwin
130
+ 'aarch64'
131
+ else
132
+ 'arm'
133
+ end
134
+ else
135
+ RbConfig::CONFIG['host_cpu']
136
+ end
137
+ end
138
+
139
+ private_constant :Platform
140
+
141
+ class << self
142
+ def default_sass_embedded
143
+ repo = 'sass/dart-sass-embedded'
144
+
145
+ spec = JSON.parse(File.read(File.absolute_path('package.json', __dir__)))
146
+
147
+ tag_name = spec['dependencies']['sass-embedded']
148
+
149
+ os = case Platform::OS
150
+ when 'darwin'
151
+ 'macos'
152
+ when 'linux'
153
+ 'linux'
154
+ when 'windows'
155
+ 'windows'
156
+ else
157
+ raise release_asset_not_available_error(repo, tag_name)
158
+ end
159
+
160
+ arch = case Platform::ARCH
161
+ when 'x86_64'
162
+ 'x64'
163
+ when 'i386'
164
+ 'ia32'
165
+ when 'aarch64'
166
+ Platform::OS == 'darwin' ? 'x64' : 'arm64'
167
+ else
168
+ raise release_asset_not_available_error(repo, tag_name)
169
+ end
170
+
171
+ ext = case os
172
+ when 'windows'
173
+ 'zip'
174
+ else
175
+ 'tar.gz'
176
+ end
177
+
178
+ "https://github.com/#{repo}/releases/download/#{tag_name}/sass_embedded-#{tag_name}-#{os}-#{arch}.#{ext}"
179
+ end
180
+
181
+ def default_protoc
182
+ repo = 'protocolbuffers/protobuf'
183
+
184
+ version = Gem::Dependency.new('google-protobuf').to_spec.version
185
+
186
+ tag_name = "v#{version}"
187
+
188
+ os = case Platform::OS
189
+ when 'darwin'
190
+ 'osx'
191
+ when 'linux'
192
+ 'linux'
193
+ when 'windows'
194
+ 'win'
195
+ else
196
+ raise release_asset_not_available_error(repo, tag_name)
197
+ end
198
+
199
+ arch = case Platform::ARCH
200
+ when 'aarch64'
201
+ Platform::OS == 'darwin' ? 'x86_64' : 'aarch_64'
202
+ when 'sparcv9'
203
+ 's390'
204
+ when 'i386'
205
+ 'x86_32'
206
+ when 'x86_64'
207
+ 'x86_64'
208
+ when 'powerpc64'
209
+ 'ppcle_64'
210
+ else
211
+ raise release_asset_not_available_error(repo, tag_name)
212
+ end
213
+
214
+ os_arch = case os
215
+ when 'win'
216
+ os + arch.split('_').last
217
+ else
218
+ "#{os}-#{arch}"
219
+ end
220
+
221
+ ext = 'zip'
222
+
223
+ "https://github.com/#{repo}/releases/download/#{tag_name}/protoc-#{version}-#{os_arch}.#{ext}"
224
+ end
225
+
226
+ def default_sass_embedded_protocol
227
+ stdout, stderr, status = Open3.capture3(
228
+ File.absolute_path("sass_embedded/dart-sass-embedded#{Gem.win_platform? ? '.bat' : ''}", __dir__), '--version'
229
+ )
230
+ raise stderr unless status.success?
231
+
232
+ tag_name = JSON.parse(stdout)['protocolVersion']
233
+ "https://github.com/sass/embedded-protocol/raw/#{tag_name}/embedded_sass.proto"
234
+ end
235
+
236
+ private
237
+
238
+ def release_asset_not_available_error(repo, tag_name)
239
+ NotImplementedError.new(
240
+ "Release asset for #{Platform::OS} #{Platform::ARCH} "\
241
+ "not available at https://github.com/#{repo}/releases/tag/#{tag_name}"
242
+ )
243
+ end
244
+ end
245
+ end
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
@@ -0,0 +1,13 @@
1
+ Param(
2
+ [Parameter(Mandatory)]
3
+ [ValidateNotNullOrEmpty()]
4
+ [string]$Archive,
5
+ [Parameter(Mandatory)]
6
+ [ValidateNotNullOrEmpty()]
7
+ [string]$DestinationPath
8
+ )
9
+ if (Get-Command Expand-Archive -ErrorAction SilentlyContinue) {
10
+ Get-Item $Archive | Expand-Archive -DestinationPath $DestinationPath -Force
11
+ } else {
12
+ cscript.exe unzip.vbs $Archive $DestinationPath
13
+ }
@@ -3,18 +3,23 @@
3
3
  module Sass
4
4
  # An exception thrown because a Sass compilation failed.
5
5
  class CompileError < StandardError
6
- attr_accessor :sass_stack, :span
6
+ # @return [String, nil]
7
+ attr_accessor :sass_stack
8
+
9
+ # @return [Logger::SourceSpan, nil]
10
+ attr_accessor :span
7
11
 
8
12
  def initialize(message, full_message, sass_stack, span)
9
13
  super(message)
10
- @full_message = full_message
11
- @sass_stack = sass_stack
14
+ @full_message = full_message == '' ? nil : full_message.dup
15
+ @sass_stack = sass_stack == '' ? nil : sass_stack
12
16
  @span = span
13
17
  end
14
18
 
15
- def full_message(*)
19
+ # @return [String]
20
+ def full_message(*args, **kwargs)
16
21
  if @full_message.nil?
17
- super
22
+ super(*args, **kwargs)
18
23
  else
19
24
  @full_message
20
25
  end
@@ -2,8 +2,17 @@
2
2
 
3
3
  module Sass
4
4
  # The result of compiling Sass to CSS. Returned by {Sass.compile} and {Sass.compile_string}.
5
+ #
6
+ # @see https://sass-lang.com/documentation/js-api/interfaces/CompileResult
5
7
  class CompileResult
6
- attr_reader :css, :source_map, :loaded_urls
8
+ # @return [String]
9
+ attr_reader :css
10
+
11
+ # @return [String, nil]
12
+ attr_reader :source_map
13
+
14
+ # @return [Array<String>]
15
+ attr_reader :loaded_urls
7
16
 
8
17
  def initialize(css, source_map, loaded_urls)
9
18
  @css = css
@@ -36,6 +36,8 @@ module Sass
36
36
  quiet_deps:,
37
37
  verbose:)
38
38
  await do
39
+ alert_color = $stderr.tty? if alert_color.nil?
40
+
39
41
  @function_registry = FunctionRegistry.new(functions, alert_color: alert_color)
40
42
  @importer_registry = ImporterRegistry.new(importers, load_paths, alert_color: alert_color)
41
43
  @logger_registry = LoggerRegistry.new(logger)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sass
4
4
  class Embedded
5
- VERSION = '1.0.6'
5
+ VERSION = '1.0.9'
6
6
  end
7
7
  end
data/lib/sass/embedded.rb CHANGED
@@ -14,10 +14,31 @@ module Sass
14
14
  @channel = Channel.new
15
15
  end
16
16
 
17
- # The {Embedded#compile} method.
18
- #
17
+ # Compiles the Sass file at +path+ to CSS.
18
+ # @param path [String]
19
+ # @param load_paths [Array<String>] Paths in which to look for stylesheets loaded by rules like
20
+ # {@use}[https://sass-lang.com/documentation/at-rules/use] and {@import}[https://sass-lang.com/documentation/at-rules/import].
21
+ # @param source_map [Boolean] Whether or not Sass should generate a source map.
22
+ # @param source_map_include_sources [Boolean] Whether Sass should include the sources in the generated source map.
23
+ # @param style [String, Symbol] The OutputStyle of the compiled CSS.
24
+ # @param functions [Hash<String, Proc>] Additional built-in Sass functions that are available in all stylesheets.
25
+ # @param importers [Array<Object>] Custom importers that control how Sass resolves loads from rules like
26
+ # {@use}[https://sass-lang.com/documentation/at-rules/use] and {@import}[https://sass-lang.com/documentation/at-rules/import].
27
+ # @param alert_ascii [Boolean] If this is +true+, the compiler will exclusively use ASCII characters in its error
28
+ # and warning messages. Otherwise, it may use non-ASCII Unicode characters as well.
29
+ # @param alert_color [Boolean] If this is +true+, the compiler will use ANSI color escape codes in its error and
30
+ # warning messages. If it's +false+, it won't use these. If it's +nil+, the compiler will determine whether or
31
+ # not to use colors depending on whether the user is using an interactive terminal.
32
+ # @param logger [Object] An object to use to handle warnings and/or debug messages from Sass.
33
+ # @param quiet_deps [Boolean] If this option is set to +true+, Sass won’t print warnings that are caused by
34
+ # dependencies. A “dependency” is defined as any file that’s loaded through +load_paths+ or +importer+.
35
+ # Stylesheets that are imported relative to the entrypoint are not considered dependencies.
36
+ # @param verbose [Boolean] By default, Dart Sass will print only five instances of the same deprecation warning per
37
+ # compilation to avoid deluging users in console noise. If you set verbose to +true+, it will instead print every
38
+ # deprecation warning it encounters.
19
39
  # @return [CompileResult]
20
40
  # @raise [CompileError]
41
+ # @see https://sass-lang.com/documentation/js-api/modules#compile
21
42
  def compile(path,
22
43
  load_paths: [],
23
44
 
@@ -29,7 +50,7 @@ module Sass
29
50
  importers: [],
30
51
 
31
52
  alert_ascii: false,
32
- alert_color: $stderr.tty?,
53
+ alert_color: nil,
33
54
  logger: nil,
34
55
  quiet_deps: false,
35
56
  verbose: false)
@@ -58,10 +79,35 @@ module Sass
58
79
  )
59
80
  end
60
81
 
61
- # The {Embedded#compile_string} method.
62
- #
82
+ # Compiles a stylesheet whose contents is +source+ to CSS.
83
+ # @param source [String]
84
+ # @param importer [Object] The importer to use to handle loads that are relative to the entrypoint stylesheet.
85
+ # @param load_paths [Array<String>] Paths in which to look for stylesheets loaded by rules like
86
+ # {@use}[https://sass-lang.com/documentation/at-rules/use] and {@import}[https://sass-lang.com/documentation/at-rules/import].
87
+ # @param syntax [String, Symbol] The Syntax to use to parse the entrypoint stylesheet.
88
+ # @param url [String] The canonical URL of the entrypoint stylesheet. If this is passed along with +importer+, it's
89
+ # used to resolve relative loads in the entrypoint stylesheet.
90
+ # @param source_map [Boolean] Whether or not Sass should generate a source map.
91
+ # @param source_map_include_sources [Boolean] Whether Sass should include the sources in the generated source map.
92
+ # @param style [String, Symbol] The OutputStyle of the compiled CSS.
93
+ # @param functions [Hash<String, Proc>] Additional built-in Sass functions that are available in all stylesheets.
94
+ # @param importers [Array<Object>] Custom importers that control how Sass resolves loads from rules like
95
+ # {@use}[https://sass-lang.com/documentation/at-rules/use] and {@import}[https://sass-lang.com/documentation/at-rules/import].
96
+ # @param alert_ascii [Boolean] If this is +true+, the compiler will exclusively use ASCII characters in its error
97
+ # and warning messages. Otherwise, it may use non-ASCII Unicode characters as well.
98
+ # @param alert_color [Boolean] If this is +true+, the compiler will use ANSI color escape codes in its error and
99
+ # warning messages. If it's +false+, it won't use these. If it's +nil+, the compiler will determine whether or
100
+ # not to use colors depending on whether the user is using an interactive terminal.
101
+ # @param logger [Object] An object to use to handle warnings and/or debug messages from Sass.
102
+ # @param quiet_deps [Boolean] If this option is set to +true+, Sass won’t print warnings that are caused by
103
+ # dependencies. A “dependency” is defined as any file that’s loaded through +load_paths+ or +importer+.
104
+ # Stylesheets that are imported relative to the entrypoint are not considered dependencies.
105
+ # @param verbose [Boolean] By default, Dart Sass will print only five instances of the same deprecation warning per
106
+ # compilation to avoid deluging users in console noise. If you set verbose to +true+, it will instead print every
107
+ # deprecation warning it encounters.
63
108
  # @return [CompileResult]
64
109
  # @raise [CompileError]
110
+ # @see https://sass-lang.com/documentation/js-api/modules#compileString
65
111
  def compile_string(source,
66
112
  importer: nil,
67
113
  load_paths: [],
@@ -76,7 +122,7 @@ module Sass
76
122
  importers: [],
77
123
 
78
124
  alert_ascii: false,
79
- alert_color: $stderr.tty?,
125
+ alert_color: nil,
80
126
  logger: nil,
81
127
  quiet_deps: false,
82
128
  verbose: false)
@@ -104,7 +150,8 @@ module Sass
104
150
  )
105
151
  end
106
152
 
107
- # The {Embedded#info} method.
153
+ # @return [String] Information about the Sass implementation.
154
+ # @see https://sass-lang.com/documentation/js-api/modules#info
108
155
  def info
109
156
  @info ||= "sass-embedded\t#{Host.new(@channel).version_request.implementation_version}"
110
157
  end
@@ -5,7 +5,10 @@ module Sass
5
5
  # A specific location within a source file.
6
6
  #
7
7
  # This is always associated with a {SourceSpan} which indicates which file it refers to.
8
+ #
9
+ # @see https://sass-lang.com/documentation/js-api/interfaces/SourceLocation
8
10
  class SourceLocation
11
+ # @return [Integer]
9
12
  attr_reader :offset, :line, :column
10
13
 
11
14
  def initialize(offset, line, column)
@@ -3,8 +3,17 @@
3
3
  module Sass
4
4
  module Logger
5
5
  # A span of text within a source file.
6
+ #
7
+ # @see https://sass-lang.com/documentation/js-api/interfaces/SourceSpan
6
8
  class SourceSpan
7
- attr_reader :start, :end, :text, :url, :context
9
+ # @return [SourceLocation]
10
+ attr_reader :start, :end
11
+
12
+ # @return [String]
13
+ attr_reader :text
14
+
15
+ # @return [String, nil]
16
+ attr_reader :url, :context
8
17
 
9
18
  def initialize(start, end_, text, url, context)
10
19
  @start = start
data/lib/sass/logger.rb CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Sass
4
4
  # A namespace for built-in Loggers.
5
+ #
6
+ # @see https://sass-lang.com/documentation/js-api/modules/Logger
5
7
  module Logger
6
8
  module_function
7
9
 
@@ -6,7 +6,12 @@ module Sass
6
6
  #
7
7
  # An argument list comes from a rest argument. It's distinct from a normal {List} in that it may contain a keyword
8
8
  # map as well as the positional arguments.
9
+ #
10
+ # @see https://sass-lang.com/documentation/js-api/classes/SassArgumentList
9
11
  class ArgumentList < Value::List
12
+ # @param contents [Array<Value>]
13
+ # @param keywords [Hash<::String, Value>]
14
+ # @param separator [::String]
10
15
  def initialize(contents = [], keywords = {}, separator = ',')
11
16
  super(contents, separator: separator)
12
17
 
@@ -15,6 +20,7 @@ module Sass
15
20
  @keywords = keywords.transform_keys(&:to_s).freeze
16
21
  end
17
22
 
23
+ # @return [Hash<::String, Value>]
18
24
  def keywords
19
25
  @keywords_accessed = true
20
26
  @keywords
@@ -3,31 +3,39 @@
3
3
  module Sass
4
4
  module Value
5
5
  # Sass's boolean type.
6
+ #
7
+ # @see https://sass-lang.com/documentation/js-api/classes/SassBoolean
6
8
  class Boolean
7
9
  include Value
8
10
 
11
+ # @param value [::Boolean]
9
12
  def initialize(value)
10
13
  @value = value
11
14
  end
12
15
 
16
+ # @return [::Boolean]
13
17
  attr_reader :value
14
18
 
15
- alias to_bool value
16
-
17
- def assert_boolean(_name = nil)
18
- self
19
+ # @return [Boolean]
20
+ def !
21
+ value ? Boolean::FALSE : Boolean::TRUE
19
22
  end
20
23
 
24
+ # @return [::Boolean]
21
25
  def ==(other)
22
26
  other.is_a?(Sass::Value::Boolean) && other.value == value
23
27
  end
24
28
 
29
+ # @return [Integer]
25
30
  def hash
26
31
  @hash ||= value.hash
27
32
  end
28
33
 
29
- def !
30
- value ? Boolean::FALSE : Boolean::TRUE
34
+ alias to_bool value
35
+
36
+ # @return [Boolean]
37
+ def assert_boolean(_name = nil)
38
+ self
31
39
  end
32
40
 
33
41
  # Sass's true value.