hanami-sasso 0.1.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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +19 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +102 -0
- data/Rakefile +12 -0
- data/hanami-sasso.gemspec +39 -0
- data/lib/hanami-sasso/compiler.rb +146 -0
- data/lib/hanami-sasso/configuration.rb +28 -0
- data/lib/hanami-sasso/rake_tasks.rb +34 -0
- data/lib/hanami-sasso/version.rb +7 -0
- data/lib/hanami-sasso.rb +43 -0
- metadata +123 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: dcf34040d859d4b988e52379a150972d7ecbe39a5220bf8a696bb5329a016572
|
|
4
|
+
data.tar.gz: 0c77072d4533a100af4aae20373b614360fa3feaf33821ab70dfae0b22461f1a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 484d10b56269d52e3fc5d80238a357863c792104b9e92d1a1fc1e7b430d1ce1bfd65c6d96eb5cedf7c8534e0d4f8105d597cbd4568d100267eb6d8a5950daca3
|
|
7
|
+
data.tar.gz: 4376f837b4f4a0b339b7e18e4e14eef024630b11c4c5d90c34c24bdab580830710e7786a2a84669d24be1c5127caa8f2d7cea54c8b3a7ca8b347a62c4be29ef6
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to **hanami-sasso** are documented here.
|
|
4
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
5
|
+
|
|
6
|
+
## [Unreleased]
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2026-06-14
|
|
9
|
+
|
|
10
|
+
Initial release. Requires the `sasso` gem **>= 0.2.0**; targets **Hanami 2.1+**.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `sasso:compile` / `sasso:watch` / `sasso:clobber` rake tasks that compile
|
|
15
|
+
configured Sass/SCSS entrypoints with the pure-Rust `sasso` compiler
|
|
16
|
+
in-process (no Node, no Dart, no subprocess) and write the CSS into `public/`.
|
|
17
|
+
- Runs `sasso:compile` before Hanami's `assets:precompile` on deploy.
|
|
18
|
+
- `HanamiSasso.configure` for builds / style / load_paths / source_dir /
|
|
19
|
+
build_dir / source_map (env-aware defaults: compressed + no map in production).
|
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 momiji-rs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# hanami-sasso
|
|
2
|
+
|
|
3
|
+
Compile **Sass/SCSS in [Hanami](https://hanamirb.org) 2.1+** with
|
|
4
|
+
[**sasso**](https://github.com/momiji-rs/sasso-ruby) — a pure-Rust,
|
|
5
|
+
zero-dependency, byte-for-byte [dart-sass](https://sass-lang.com) alternative.
|
|
6
|
+
|
|
7
|
+
Hanami's assets pipeline is esbuild-based with no native Sass step. This gem adds
|
|
8
|
+
`sasso:compile` / `sasso:watch` / `sasso:clobber` rake tasks that compile your
|
|
9
|
+
Sass/SCSS **in-process** — no Node toolchain, no Dart VM, no subprocess — and
|
|
10
|
+
write the CSS straight into `public/`.
|
|
11
|
+
|
|
12
|
+
- **No Node for CSS.** Compile Sass with zero JavaScript tooling.
|
|
13
|
+
- **In-process.** No process spawn per build — sasso is a native Ruby gem.
|
|
14
|
+
- **Byte-for-byte dart-sass.** Same CSS as `dart-sass`, just faster.
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```ruby
|
|
19
|
+
# Gemfile
|
|
20
|
+
gem "hanami-sasso"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
bundle install
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Load the rake tasks from your `Rakefile` (after Hanami's, so the
|
|
28
|
+
`assets:precompile` hook attaches):
|
|
29
|
+
|
|
30
|
+
```ruby
|
|
31
|
+
# Rakefile
|
|
32
|
+
require "hanami/rake_tasks"
|
|
33
|
+
require "hanami-sasso/rake_tasks"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Put your entrypoint (and partials) in `app/assets/css/` — e.g.
|
|
37
|
+
`app/assets/css/app.scss`. Compile it:
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
bundle exec rake sasso:compile # -> public/assets/css/app.css
|
|
41
|
+
bundle exec rake sasso:watch # recompile on change
|
|
42
|
+
bundle exec rake sasso:clobber # remove generated CSS
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`sasso:compile` runs automatically before `assets:precompile`, so deploys
|
|
46
|
+
regenerate the CSS. Link it from your layout:
|
|
47
|
+
|
|
48
|
+
```erb
|
|
49
|
+
<link rel="stylesheet" href="/assets/css/app.css">
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Configuration
|
|
53
|
+
|
|
54
|
+
Configure in your `Rakefile` (or a `config/sasso.rb` you require) — all optional,
|
|
55
|
+
defaults shown:
|
|
56
|
+
|
|
57
|
+
```ruby
|
|
58
|
+
HanamiSasso.configure do |c|
|
|
59
|
+
# { "<input under source_dir>" => "<output under build_dir>" }
|
|
60
|
+
c.builds = { "app.scss" => "app.css" }
|
|
61
|
+
# nil = :compressed in production (HANAMI_ENV=production), :expanded else.
|
|
62
|
+
c.style = nil
|
|
63
|
+
c.load_paths = [] # extra @use/@import dirs
|
|
64
|
+
c.source_dir = "app/assets/css"
|
|
65
|
+
c.build_dir = "public/assets/css" # compiled straight into public/
|
|
66
|
+
c.source_map = nil # nil = sidecar .map outside production
|
|
67
|
+
end
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
> **Prefer Hanami's esbuild pipeline?** Set `c.build_dir = "app/assets/css"` and
|
|
71
|
+
> `import` the compiled `.css` from `app/assets/js/app.js`; esbuild will then
|
|
72
|
+
> bundle and fingerprint it. The default compiles straight into `public/` so
|
|
73
|
+
> CSS needs no Node at all.
|
|
74
|
+
|
|
75
|
+
## Performance
|
|
76
|
+
|
|
77
|
+
`sasso` compiles the same CSS as dart-sass, byte-for-byte, but much faster — and
|
|
78
|
+
with no Node runtime. Benchmarked on an Apple M2 Max, all engines dart-sass
|
|
79
|
+
1.101, against the Node frontend's default Sass engine (`sass`, dart2js):
|
|
80
|
+
|
|
81
|
+
**In-process** (how this gem compiles — inside the Ruby process):
|
|
82
|
+
|
|
83
|
+
| workload | hanami-sasso | Node `sass` (dart2js) |
|
|
84
|
+
|----------|--------------|-----------------------|
|
|
85
|
+
| ~360 rules | **1.2 ms** | 8.0 ms (**6.4× slower**) |
|
|
86
|
+
| ~3000 rules | **9.9 ms** | 71.5 ms (**7.2× slower**) |
|
|
87
|
+
|
|
88
|
+
**Cold per-build** (one-shot compile incl. runtime startup):
|
|
89
|
+
|
|
90
|
+
| workload | hanami-sasso | dart-sass (native) | Node `sass` (dart2js) |
|
|
91
|
+
|----------|--------------|--------------------|-----------------------|
|
|
92
|
+
| ~360 rules | **3.0 ms** | 27.5 ms (9×) | 185 ms (**63× slower**) |
|
|
93
|
+
| ~3000 rules | **10.9 ms** | 64.2 ms (6×) | 348 ms (**32× slower**) |
|
|
94
|
+
|
|
95
|
+
Output is byte-identical to dart-sass, so this is pure speedup with no behavior
|
|
96
|
+
change. (Synthetic workloads; ratios are the takeaway, absolute numbers are
|
|
97
|
+
machine-specific.)
|
|
98
|
+
|
|
99
|
+
## License
|
|
100
|
+
|
|
101
|
+
MIT, matching the Sass ecosystem. (The core `sasso` compiler crate is dual
|
|
102
|
+
MIT OR Apache-2.0.)
|
data/Rakefile
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lib/hanami-sasso/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "hanami-sasso"
|
|
7
|
+
spec.version = HanamiSasso::VERSION
|
|
8
|
+
spec.author = "momiji-rs"
|
|
9
|
+
spec.summary = "Compile Sass/SCSS in Hanami with the pure-Rust sasso compiler — no Node, no Dart"
|
|
10
|
+
spec.description = "A Hanami integration for sasso, a pure-Rust, zero-dependency, byte-for-byte " \
|
|
11
|
+
"dart-sass alternative. Adds sasso:compile/watch/clobber rake tasks (and runs " \
|
|
12
|
+
"before assets:precompile) that compile your Sass/SCSS in-process — no Node " \
|
|
13
|
+
"toolchain, no Dart VM, no subprocess. For Hanami 2.1+."
|
|
14
|
+
spec.homepage = "https://github.com/momiji-rs/hanami-sasso"
|
|
15
|
+
spec.license = "MIT"
|
|
16
|
+
|
|
17
|
+
spec.metadata = {
|
|
18
|
+
"homepage_uri" => spec.homepage,
|
|
19
|
+
"source_code_uri" => spec.homepage,
|
|
20
|
+
"changelog_uri" => "#{spec.homepage}/blob/main/CHANGELOG.md",
|
|
21
|
+
"rubygems_mfa_required" => "true",
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
25
|
+
f.match(%r{^(test|script|spec|features)/}) || f.match(%r{^\.})
|
|
26
|
+
end
|
|
27
|
+
spec.require_paths = ["lib"]
|
|
28
|
+
|
|
29
|
+
spec.required_ruby_version = ">= 3.1.0"
|
|
30
|
+
|
|
31
|
+
# The gem's runtime code requires only the compiler (+ Rake for the tasks); it
|
|
32
|
+
# integrates with Hanami's `assets:precompile` when present but never loads the
|
|
33
|
+
# framework itself. Targets Hanami 2.1+.
|
|
34
|
+
spec.add_dependency "rake", ">= 13.0"
|
|
35
|
+
spec.add_dependency "sasso", ">= 0.2.0", "< 1"
|
|
36
|
+
|
|
37
|
+
spec.add_development_dependency "bundler"
|
|
38
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
|
39
|
+
end
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "fileutils"
|
|
4
|
+
require "json"
|
|
5
|
+
require "pathname"
|
|
6
|
+
require "sasso"
|
|
7
|
+
|
|
8
|
+
module HanamiSasso
|
|
9
|
+
# Compiles configured Sass/SCSS entrypoints to plain CSS files. Deliberately
|
|
10
|
+
# framework-free so it can be unit-tested with a plain temp `root:` — the rake
|
|
11
|
+
# tasks just wire the Hanami app root + configuration in.
|
|
12
|
+
#
|
|
13
|
+
# HanamiSasso::Compiler.new(
|
|
14
|
+
# root: Dir.pwd,
|
|
15
|
+
# builds: { "app.scss" => "app.css" },
|
|
16
|
+
# style: :expanded,
|
|
17
|
+
# load_paths: [], # extra dirs, in addition to the source dir
|
|
18
|
+
# source_dir: "app/assets/css",
|
|
19
|
+
# build_dir: "public/assets/css",
|
|
20
|
+
# ).build
|
|
21
|
+
class Compiler
|
|
22
|
+
Error = Class.new(StandardError)
|
|
23
|
+
|
|
24
|
+
ALLOWED_STYLES = %i[expanded compressed].freeze
|
|
25
|
+
|
|
26
|
+
attr_reader :root, :builds, :style, :load_paths, :source_dir, :build_dir, :source_map
|
|
27
|
+
|
|
28
|
+
def initialize(root:, builds:, style: :expanded, load_paths: [],
|
|
29
|
+
source_dir: "app/assets/css",
|
|
30
|
+
build_dir: "public/assets/css", source_map: false)
|
|
31
|
+
@root = File.expand_path(root.to_s)
|
|
32
|
+
@builds = normalize_builds(builds)
|
|
33
|
+
@style = normalize_style(style)
|
|
34
|
+
@load_paths = Array(load_paths).map(&:to_s)
|
|
35
|
+
@source_dir = source_dir.to_s
|
|
36
|
+
@build_dir = build_dir.to_s
|
|
37
|
+
@source_map = source_map ? true : false
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Compile every entrypoint; returns the list of written output paths.
|
|
41
|
+
def build
|
|
42
|
+
builds.map { |input, output| build_one(input, output) }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Remove the generated CSS (and any sidecar maps) for every entrypoint.
|
|
46
|
+
def clobber
|
|
47
|
+
builds.filter_map do |_input, output|
|
|
48
|
+
dest = File.join(@root, @build_dir, output)
|
|
49
|
+
[dest, "#{dest}.map"].select { |f| File.file?(f) }.each { |f| FileUtils.rm_f(f) }
|
|
50
|
+
File.directory?(File.dirname(dest)) ? dest : nil
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Compile a single `input` (relative to source_dir) to `output` (relative to
|
|
55
|
+
# build_dir), returning the absolute path written.
|
|
56
|
+
def build_one(input, output)
|
|
57
|
+
src = File.join(@root, @source_dir, input)
|
|
58
|
+
raise Error, "hanami-sasso: input stylesheet not found: #{src}" unless File.file?(src)
|
|
59
|
+
|
|
60
|
+
dest = File.join(@root, @build_dir, output)
|
|
61
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
|
62
|
+
|
|
63
|
+
# `Sasso.compile` already searches the entry file's own directory first
|
|
64
|
+
# (for sibling @use/@import); pass any extra include dirs after it.
|
|
65
|
+
if @source_map
|
|
66
|
+
result = ::Sasso.compile(src, style: @style, load_paths: @load_paths, source_map: true)
|
|
67
|
+
write_source_map(dest, result.source_map)
|
|
68
|
+
File.write(dest, result.css + source_map_footer(File.basename(dest)))
|
|
69
|
+
else
|
|
70
|
+
File.write(dest, ::Sasso.compile(src, style: @style, load_paths: @load_paths))
|
|
71
|
+
end
|
|
72
|
+
dest
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Recompile whenever a watched source file changes. Dependency-free poll loop
|
|
76
|
+
# (no `listen` gem): a cheap mtime scan of the source + load_path trees.
|
|
77
|
+
# Blocks. A compile error (including on the FIRST pass) is reported and the
|
|
78
|
+
# loop keeps running — the watcher must survive a mid-edit broken file.
|
|
79
|
+
def watch(interval: 1.0)
|
|
80
|
+
safe_build
|
|
81
|
+
snapshot = source_mtimes
|
|
82
|
+
loop do
|
|
83
|
+
sleep interval
|
|
84
|
+
current = source_mtimes
|
|
85
|
+
next if current == snapshot
|
|
86
|
+
|
|
87
|
+
snapshot = current
|
|
88
|
+
safe_build
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
private
|
|
93
|
+
|
|
94
|
+
def write_source_map(dest, source_map)
|
|
95
|
+
from_dir = File.dirname(dest)
|
|
96
|
+
source_map["file"] = File.basename(dest)
|
|
97
|
+
source_map["sources"] = Array(source_map["sources"]).map { |s| relative_source(s, from_dir) }
|
|
98
|
+
File.write("#{dest}.map", JSON.generate(source_map))
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def source_map_footer(css_basename)
|
|
102
|
+
comment = "/*# sourceMappingURL=#{css_basename}.map */"
|
|
103
|
+
@style == :compressed ? "#{comment}\n" : "\n#{comment}\n"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def relative_source(url, from_dir)
|
|
107
|
+
Pathname.new(url).relative_path_from(Pathname.new(from_dir)).to_s
|
|
108
|
+
rescue ArgumentError
|
|
109
|
+
url
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def safe_build
|
|
113
|
+
build
|
|
114
|
+
rescue ::Sasso::CompileError, Error => e
|
|
115
|
+
warn e.message
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def source_mtimes
|
|
119
|
+
dirs = [File.join(@root, @source_dir), *@load_paths]
|
|
120
|
+
dirs.flat_map { |d| Dir.glob(File.join(d, "**", "*.{scss,sass}")) }
|
|
121
|
+
.uniq.sort.each_with_object({}) do |f, h|
|
|
122
|
+
h[f] = File.mtime(f).to_f
|
|
123
|
+
rescue Errno::ENOENT
|
|
124
|
+
# raced with a delete; skip
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def normalize_builds(builds)
|
|
129
|
+
hash = builds.respond_to?(:to_h) ? builds.to_h : nil
|
|
130
|
+
if hash.nil? || hash.empty?
|
|
131
|
+
raise Error, 'hanami-sasso: builds must be a non-empty Hash of { "input.scss" => "output.css" }'
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
hash
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def normalize_style(style)
|
|
138
|
+
sym = style.to_s.to_sym
|
|
139
|
+
unless ALLOWED_STYLES.include?(sym)
|
|
140
|
+
raise Error, "hanami-sasso: style must be one of #{ALLOWED_STYLES.inspect}, got #{style.inspect}"
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
sym
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module HanamiSasso
|
|
4
|
+
# Plugin configuration. Set it from your Rakefile (or a `config/sasso.rb` you
|
|
5
|
+
# require) with `HanamiSasso.configure { |c| ... }`. Defaults target a stock
|
|
6
|
+
# Hanami 2 layout and compile directly to `public/` (no Node, no esbuild).
|
|
7
|
+
class Configuration
|
|
8
|
+
attr_accessor :builds, :style, :load_paths, :source_dir, :build_dir, :source_map, :root
|
|
9
|
+
|
|
10
|
+
def initialize
|
|
11
|
+
# { "<input under source_dir>" => "<output under build_dir>" }
|
|
12
|
+
@builds = { "app.scss" => "app.css" }
|
|
13
|
+
# nil = :compressed in production (HANAMI_ENV=production), :expanded else.
|
|
14
|
+
@style = nil
|
|
15
|
+
# Extra @use/@import dirs; the entrypoint's own dir is always searched.
|
|
16
|
+
@load_paths = []
|
|
17
|
+
@source_dir = "app/assets/css"
|
|
18
|
+
# Compile straight into public/ so the CSS is served with no Node/esbuild
|
|
19
|
+
# step; link it with <link href="/assets/css/app.css">. Point this at
|
|
20
|
+
# "app/assets/css" instead if you'd rather feed Hanami's esbuild pipeline.
|
|
21
|
+
@build_dir = "public/assets/css"
|
|
22
|
+
# nil = sidecar .map outside production, off in production; true/false force.
|
|
23
|
+
@source_map = nil
|
|
24
|
+
# nil = the working dir when the task runs (the Hanami app root).
|
|
25
|
+
@root = nil
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rake"
|
|
4
|
+
require "hanami-sasso"
|
|
5
|
+
|
|
6
|
+
# Adds `sasso:compile` / `sasso:watch` / `sasso:clobber`, and runs `sasso:compile`
|
|
7
|
+
# before Hanami's `assets:precompile` on deploy. Require this AFTER
|
|
8
|
+
# `require "hanami/rake_tasks"` in your Rakefile so the precompile hook attaches:
|
|
9
|
+
#
|
|
10
|
+
# # Rakefile
|
|
11
|
+
# require "hanami/rake_tasks"
|
|
12
|
+
# require "hanami-sasso/rake_tasks"
|
|
13
|
+
# HanamiSasso.configure { |c| c.builds = { "app.scss" => "app.css" } } # optional
|
|
14
|
+
|
|
15
|
+
namespace :sasso do
|
|
16
|
+
desc "Compile Sass/SCSS entrypoints with sasso"
|
|
17
|
+
task :compile do
|
|
18
|
+
HanamiSasso.compiler.build
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
desc "Watch sources and recompile on change"
|
|
22
|
+
task :watch do
|
|
23
|
+
HanamiSasso.compiler.watch
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
desc "Remove the generated CSS"
|
|
27
|
+
task :clobber do
|
|
28
|
+
HanamiSasso.compiler.clobber
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Compile before Hanami fingerprints/serves assets on deploy. No-op if the
|
|
33
|
+
# Hanami assets tasks weren't loaded before this file.
|
|
34
|
+
Rake::Task["assets:precompile"].enhance(["sasso:compile"]) if Rake::Task.task_defined?("assets:precompile")
|
data/lib/hanami-sasso.rb
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "hanami-sasso/version"
|
|
4
|
+
require "hanami-sasso/configuration"
|
|
5
|
+
require "hanami-sasso/compiler"
|
|
6
|
+
|
|
7
|
+
# Compile Sass/SCSS in a Hanami app with the pure-Rust `sasso` compiler — no
|
|
8
|
+
# Node, no Dart, no subprocess. Provide the rake tasks by requiring
|
|
9
|
+
# "hanami-sasso/rake_tasks" from your Rakefile.
|
|
10
|
+
module HanamiSasso
|
|
11
|
+
class << self
|
|
12
|
+
def config
|
|
13
|
+
@config ||= Configuration.new
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def configure
|
|
17
|
+
yield(config)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def reset_configuration!
|
|
21
|
+
@config = Configuration.new
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def production?
|
|
25
|
+
(ENV["HANAMI_ENV"] || ENV["RACK_ENV"] || "development").to_s == "production"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Build a Compiler from the current configuration, resolving the env-aware
|
|
29
|
+
# defaults (style + source maps) to concrete values.
|
|
30
|
+
def compiler
|
|
31
|
+
c = config
|
|
32
|
+
Compiler.new(
|
|
33
|
+
root: c.root || Dir.pwd,
|
|
34
|
+
builds: c.builds,
|
|
35
|
+
style: c.style || (production? ? :compressed : :expanded),
|
|
36
|
+
load_paths: c.load_paths,
|
|
37
|
+
source_dir: c.source_dir,
|
|
38
|
+
build_dir: c.build_dir,
|
|
39
|
+
source_map: c.source_map.nil? ? !production? : c.source_map
|
|
40
|
+
)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: hanami-sasso
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- momiji-rs
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-06-14 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rake
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '13.0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '13.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: sasso
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: 0.2.0
|
|
34
|
+
- - "<"
|
|
35
|
+
- !ruby/object:Gem::Version
|
|
36
|
+
version: '1'
|
|
37
|
+
type: :runtime
|
|
38
|
+
prerelease: false
|
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
40
|
+
requirements:
|
|
41
|
+
- - ">="
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: 0.2.0
|
|
44
|
+
- - "<"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '1'
|
|
47
|
+
- !ruby/object:Gem::Dependency
|
|
48
|
+
name: bundler
|
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
type: :development
|
|
55
|
+
prerelease: false
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
- !ruby/object:Gem::Dependency
|
|
62
|
+
name: minitest
|
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '5.0'
|
|
68
|
+
type: :development
|
|
69
|
+
prerelease: false
|
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '5.0'
|
|
75
|
+
description: A Hanami integration for sasso, a pure-Rust, zero-dependency, byte-for-byte
|
|
76
|
+
dart-sass alternative. Adds sasso:compile/watch/clobber rake tasks (and runs before
|
|
77
|
+
assets:precompile) that compile your Sass/SCSS in-process — no Node toolchain, no
|
|
78
|
+
Dart VM, no subprocess. For Hanami 2.1+.
|
|
79
|
+
email:
|
|
80
|
+
executables: []
|
|
81
|
+
extensions: []
|
|
82
|
+
extra_rdoc_files: []
|
|
83
|
+
files:
|
|
84
|
+
- CHANGELOG.md
|
|
85
|
+
- Gemfile
|
|
86
|
+
- LICENSE
|
|
87
|
+
- README.md
|
|
88
|
+
- Rakefile
|
|
89
|
+
- hanami-sasso.gemspec
|
|
90
|
+
- lib/hanami-sasso.rb
|
|
91
|
+
- lib/hanami-sasso/compiler.rb
|
|
92
|
+
- lib/hanami-sasso/configuration.rb
|
|
93
|
+
- lib/hanami-sasso/rake_tasks.rb
|
|
94
|
+
- lib/hanami-sasso/version.rb
|
|
95
|
+
homepage: https://github.com/momiji-rs/hanami-sasso
|
|
96
|
+
licenses:
|
|
97
|
+
- MIT
|
|
98
|
+
metadata:
|
|
99
|
+
homepage_uri: https://github.com/momiji-rs/hanami-sasso
|
|
100
|
+
source_code_uri: https://github.com/momiji-rs/hanami-sasso
|
|
101
|
+
changelog_uri: https://github.com/momiji-rs/hanami-sasso/blob/main/CHANGELOG.md
|
|
102
|
+
rubygems_mfa_required: 'true'
|
|
103
|
+
post_install_message:
|
|
104
|
+
rdoc_options: []
|
|
105
|
+
require_paths:
|
|
106
|
+
- lib
|
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
108
|
+
requirements:
|
|
109
|
+
- - ">="
|
|
110
|
+
- !ruby/object:Gem::Version
|
|
111
|
+
version: 3.1.0
|
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - ">="
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '0'
|
|
117
|
+
requirements: []
|
|
118
|
+
rubygems_version: 3.5.22
|
|
119
|
+
signing_key:
|
|
120
|
+
specification_version: 4
|
|
121
|
+
summary: Compile Sass/SCSS in Hanami with the pure-Rust sasso compiler — no Node,
|
|
122
|
+
no Dart
|
|
123
|
+
test_files: []
|