sasso-rails 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ec674d60203b29114c080883f7e4cf438fa36dbc8b43daaebb02f7d197ffbf2e
4
+ data.tar.gz: cd677fde1997dae468d8ad8acdd4de81a41847931ba6f72a9d7b102cfe523bbe
5
+ SHA512:
6
+ metadata.gz: ca83ee104decbe95b065399c956584959c4f8599658c590c90c371859a920562f611eb7d41171d53e1581a3d66160ccb5bd02fd2545986ad87c9fba975075079
7
+ data.tar.gz: 9df668f046ac42666b9ab9e65aba3b0b29fe3dfb0d018ccf8f7afc821f8f4378e76afbf0b5ca151ac6efc9b987a52160f0279fdcfeaa55215e3bb3738c39347c
data/CHANGELOG.md ADDED
@@ -0,0 +1,29 @@
1
+ # Changelog
2
+
3
+ All notable changes to the **sasso-rails** gem are documented here.
4
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
+
6
+ This gem versions independently of the `sasso` compiler gem; each release notes
7
+ the engine-gem version range it requires.
8
+
9
+ ## [Unreleased]
10
+
11
+ ## [0.1.0] - 2026-06-13
12
+
13
+ Initial release. Requires the `sasso` gem **>= 0.1.1, < 1**.
14
+
15
+ ### Added
16
+
17
+ - `Sasso::Rails::Engine` — wires sasso into a Rails app with `config.sasso.*`
18
+ (`builds`, `style`, `load_paths`, `source_dir`, `build_dir`).
19
+ - Rake tasks `sasso:build`, `sasso:watch`, and `sasso:clobber`; `sasso:build`
20
+ is enhanced onto `assets:precompile` (and `sasso:clobber` onto
21
+ `assets:clobber`).
22
+ - `Sasso::Rails::Compiler` — Rails-free build object; compiles each entrypoint
23
+ with the in-process `Sasso.compile` (no subprocess / Node.js) and writes to
24
+ `app/assets/builds`.
25
+ - `bin/rails sasso:install` generator: scaffolds `application.scss`, the builds
26
+ directory, a Sprockets manifest link (when present), and a `Procfile.dev`
27
+ watch process.
28
+ - Propshaft-first, Sprockets-compatible (compiled CSS is served as a static
29
+ build artifact by either pipeline).
data/LICENSE-MIT ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 linyiru
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,115 @@
1
+ # sasso-rails
2
+
3
+ Rails integration for [**sasso**](https://github.com/momiji-rs/sasso-ruby) — a
4
+ pure-Rust, zero-dependency SCSS/Sass → CSS compiler (a byte-for-byte dart-sass
5
+ alternative).
6
+
7
+ Compiles your stylesheets into `app/assets/builds/` for the Rails asset
8
+ pipeline to serve. **Propshaft-first** (the Rails 8 default) and
9
+ Sprockets-compatible.
10
+
11
+ Why this gem over the alternatives:
12
+
13
+ - **No Node.js.** Unlike `cssbundling-rails`, there is no `node`/`yarn`/`npx`
14
+ requirement — the compiler ships as a precompiled Ruby native gem.
15
+ - **In-process, no subprocess.** Unlike `dartsass-rails` / `tailwindcss-rails`
16
+ (which shell out to a standalone binary), sasso-rails calls `Sasso.compile`
17
+ directly through the native extension — no process spawn, no IPC.
18
+ - **Pure Rust core.** No libsass (deprecated), no Dart VM.
19
+
20
+ ## Installation
21
+
22
+ ```ruby
23
+ # Gemfile
24
+ gem "sasso-rails"
25
+ ```
26
+
27
+ ```sh
28
+ bundle install
29
+ bin/rails generate sasso:install
30
+ ```
31
+
32
+ The installer scaffolds `app/assets/stylesheets/application.scss`, creates
33
+ `app/assets/builds/` (with a `.keep`), links the builds directory in a Sprockets
34
+ manifest if one exists, and adds a watch process to `Procfile.dev`.
35
+
36
+ Reference the compiled CSS in your layout:
37
+
38
+ ```erb
39
+ <%= stylesheet_link_tag "application" %>
40
+ ```
41
+
42
+ ## Usage
43
+
44
+ ```sh
45
+ bin/rails sasso:build # compile once
46
+ bin/rails sasso:watch # recompile on change (or run ./bin/dev)
47
+ bin/rails sasso:clobber # remove generated CSS
48
+ ```
49
+
50
+ `sasso:build` runs automatically before `assets:precompile`, so deploys
51
+ (`rails assets:precompile`) regenerate the CSS before the pipeline fingerprints
52
+ it. No extra deploy wiring needed.
53
+
54
+ ## Configuration
55
+
56
+ In `config/application.rb` (or an environment file):
57
+
58
+ ```ruby
59
+ # Map each entrypoint (under source_dir) to an output file (under build_dir).
60
+ config.sasso.builds = {
61
+ "application.scss" => "application.css",
62
+ "admin.scss" => "admin.css",
63
+ }
64
+
65
+ # :expanded | :compressed. Default: :compressed in production, :expanded else.
66
+ config.sasso.style = :compressed
67
+
68
+ # Extra @use/@import include dirs. The entrypoint's own directory is always
69
+ # searched first, so sibling partials need no configuration.
70
+ config.sasso.load_paths = [Rails.root.join("vendor/styles").to_s]
71
+
72
+ # Defaults shown:
73
+ config.sasso.source_dir = "app/assets/stylesheets"
74
+ config.sasso.build_dir = "app/assets/builds"
75
+ ```
76
+
77
+ ## How it fits the pipeline
78
+
79
+ `sasso:build` writes plain CSS to `app/assets/builds/`. Both pipelines treat
80
+ that directory as a source of ready-to-serve assets:
81
+
82
+ - **Propshaft** (Rails 8 default) discovers `app/assets/builds` on its load
83
+ path, fingerprints the CSS, and rewrites `url(...)` references — it performs
84
+ no Sass compilation itself.
85
+ - **Sprockets** serves the built CSS as a static asset (the installer adds
86
+ `//= link_tree ../builds` to `app/assets/config/manifest.js`).
87
+
88
+ ## Notes & limitations
89
+
90
+ - **Source maps are not supported yet.** The in-process compiler returns CSS
91
+ only; there is no `.css.map` output in any environment.
92
+ - **`builds` is file-to-file.** Each entry maps one input file to one output
93
+ file. There is no directory-glob form (no `"." => "."`); list each entrypoint
94
+ explicitly.
95
+ - **Load paths are explicit.** Only the entrypoint's own directory (searched
96
+ automatically) and `config.sasso.load_paths` are on the `@use`/`@import`
97
+ search path. Gem-vendored or `config.assets.paths` stylesheets are NOT added
98
+ automatically — list their directories in `config.sasso.load_paths`.
99
+ - **No double-minification.** On a Sprockets app that sets
100
+ `config.assets.css_compressor`, sasso-rails stays `:expanded` and lets the
101
+ pipeline compress (unless you pin `config.sasso.style`). Propshaft does not
102
+ compress, so production output is `:compressed` there.
103
+ - **Watch is a 1s mtime poll** (dependency-free, no native fs-events); it covers
104
+ the source dir and `config.sasso.load_paths`.
105
+
106
+ ## Versioning
107
+
108
+ This gem versions independently of the `sasso` compiler gem and pins it with a
109
+ range (`sasso >= 0.1.1, < 1`). An app may pin a specific compiler version in its
110
+ own `Gemfile`.
111
+
112
+ ## License
113
+
114
+ MIT, matching the Sass ecosystem. (The core `sasso` compiler crate remains
115
+ dual-licensed MIT OR Apache-2.0.)
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/base"
4
+
5
+ module Sasso
6
+ module Generators
7
+ # `bin/rails sasso:install` — scaffolds the entrypoint + build dir and wires
8
+ # a dev watch process, mirroring the dartsass/tailwindcss install flow.
9
+ class InstallGenerator < ::Rails::Generators::Base
10
+ source_root File.expand_path("templates", __dir__)
11
+
12
+ def create_stylesheet
13
+ template "application.scss", "app/assets/stylesheets/application.scss"
14
+ end
15
+
16
+ def ensure_builds_directory
17
+ create_file "app/assets/builds/.keep" unless File.exist?(builds_keep_path)
18
+
19
+ rules = "/app/assets/builds/*\n!/app/assets/builds/.keep\n"
20
+ if File.exist?(gitignore_path)
21
+ # Idempotent: skip if already present (re-running the installer).
22
+ append_to_file ".gitignore", rules unless File.read(gitignore_path).include?("/app/assets/builds/")
23
+ else
24
+ # No .gitignore at all — create one so generated CSS isn't committed.
25
+ create_file ".gitignore", rules
26
+ end
27
+ end
28
+
29
+ # Sprockets-only apps must link the builds directory in the manifest;
30
+ # Propshaft discovers it automatically, so guard on the manifest existing.
31
+ def link_builds_in_sprockets_manifest
32
+ manifest = "app/assets/config/manifest.js"
33
+ full = File.join(destination_root, manifest)
34
+ return unless File.exist?(full)
35
+ return if File.read(full).include?("link_tree ../builds")
36
+
37
+ append_to_file manifest, %(//= link_tree ../builds\n)
38
+ end
39
+
40
+ def add_watch_to_procfile
41
+ procfile = "Procfile.dev"
42
+ full = File.join(destination_root, procfile)
43
+ if File.exist?(full)
44
+ append_to_file procfile, "css: bin/rails sasso:watch\n" unless File.read(full).include?("sasso:watch")
45
+ else
46
+ create_file procfile, <<~PROCFILE
47
+ web: bin/rails server
48
+ css: bin/rails sasso:watch
49
+ PROCFILE
50
+ end
51
+ end
52
+
53
+ # Compile once so `app/assets/builds/application.css` exists and the first
54
+ # page load (stylesheet_link_tag "application") doesn't 404.
55
+ def build_initial_css
56
+ rails_command "sasso:build"
57
+ end
58
+
59
+ def print_instructions
60
+ say ""
61
+ say "sasso-rails installed.", :green
62
+ say " • Edit app/assets/stylesheets/application.scss"
63
+ say " • Reference it with: <%= stylesheet_link_tag \"application\" %>"
64
+ say " • Build once: bin/rails sasso:build"
65
+ say " • Watch in dev: bin/rails sasso:watch"
66
+ say " (or ./bin/dev, if your app has a Procfile.dev runner like foreman)"
67
+ end
68
+
69
+ private
70
+
71
+ def builds_keep_path
72
+ File.join(destination_root, "app/assets/builds/.keep")
73
+ end
74
+
75
+ def gitignore_path
76
+ File.join(destination_root, ".gitignore")
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,13 @@
1
+ // Entrypoint for sasso-rails. This file is compiled by `sasso:build` to
2
+ // app/assets/builds/application.css, which the asset pipeline serves.
3
+ //
4
+ // Use @use to pull in partials (files named _name.scss) from this directory:
5
+ //
6
+ // @use "components/buttons";
7
+ //
8
+ // Sibling partials resolve automatically; add extra include dirs via
9
+ // config.sasso.load_paths in config/application.rb.
10
+
11
+ body {
12
+ margin: 0;
13
+ }
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+
5
+ module Sasso
6
+ module Rails
7
+ # Compiles configured Sass/SCSS entrypoints to plain CSS files under the
8
+ # builds directory. Deliberately Rails-free so it can be unit-tested with a
9
+ # plain temp `root:` — the Engine just wires `Rails.root` and config in.
10
+ #
11
+ # Sasso::Rails::Compiler.new(
12
+ # root: Rails.root,
13
+ # builds: { "application.scss" => "application.css" },
14
+ # style: :expanded,
15
+ # load_paths: [], # extra dirs, in addition to the source dir
16
+ # source_dir: "app/assets/stylesheets",
17
+ # build_dir: "app/assets/builds",
18
+ # ).build
19
+ class Compiler
20
+ Error = Class.new(StandardError)
21
+
22
+ ALLOWED_STYLES = %i[expanded compressed].freeze
23
+
24
+ attr_reader :root, :builds, :style, :load_paths, :source_dir, :build_dir
25
+
26
+ def initialize(root:, builds:, style: :expanded, load_paths: [],
27
+ source_dir: "app/assets/stylesheets",
28
+ build_dir: "app/assets/builds")
29
+ @root = File.expand_path(root.to_s)
30
+ @builds = normalize_builds(builds)
31
+ @style = normalize_style(style)
32
+ @load_paths = Array(load_paths).map(&:to_s)
33
+ @source_dir = source_dir.to_s
34
+ @build_dir = build_dir.to_s
35
+ end
36
+
37
+ # Compile every entrypoint; returns the list of written output paths.
38
+ def build
39
+ builds.map { |input, output| build_one(input, output) }
40
+ end
41
+
42
+ # Compile a single `input` (relative to source_dir) to `output` (relative
43
+ # to build_dir), returning the absolute path written.
44
+ def build_one(input, output)
45
+ src = File.join(@root, @source_dir, input)
46
+ unless File.file?(src)
47
+ raise Error, "sasso-rails: input stylesheet not found: #{src}"
48
+ end
49
+
50
+ # `Sasso.compile` already searches the entry file's own directory first
51
+ # (for sibling @use/@import); pass any extra include dirs after it.
52
+ css = ::Sasso.compile(src, style: @style, load_paths: @load_paths)
53
+
54
+ dest = File.join(@root, @build_dir, output)
55
+ FileUtils.mkdir_p(File.dirname(dest))
56
+ File.write(dest, css)
57
+ dest
58
+ end
59
+
60
+ # Recompile whenever a watched source file changes. Dependency-free poll
61
+ # loop (no `listen` gem): cheap mtime scan of the source + load_path trees.
62
+ # Blocks. A compile error (including on the FIRST pass) is reported and the
63
+ # loop keeps running — the watcher must survive a mid-edit broken file.
64
+ def watch(interval: 1.0)
65
+ safe_build
66
+ snapshot = source_mtimes
67
+ loop do
68
+ sleep interval
69
+ current = source_mtimes
70
+ next if current == snapshot
71
+
72
+ snapshot = current
73
+ safe_build
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ # Compile, downgrading a Sass/config error to a warning so a watcher does
80
+ # not die on it (used at startup and on every recompile).
81
+ def safe_build
82
+ build
83
+ rescue ::Sasso::CompileError, Error => e
84
+ warn e.message
85
+ end
86
+
87
+ # mtime of every .scss/.sass under the source dir AND the configured
88
+ # load_paths (so editing a shared partial in an include dir also rebuilds).
89
+ def source_mtimes
90
+ dirs = [File.join(@root, @source_dir), *@load_paths]
91
+ dirs.flat_map { |d| Dir.glob(File.join(d, "**", "*.{scss,sass}")) }
92
+ .uniq.sort.each_with_object({}) do |f, h|
93
+ h[f] = File.mtime(f).to_f
94
+ rescue Errno::ENOENT
95
+ # raced with a delete; skip
96
+ end
97
+ end
98
+
99
+ # config.sasso.builds must be a non-empty { "input" => "output" } map.
100
+ def normalize_builds(builds)
101
+ hash = builds.respond_to?(:to_h) ? builds.to_h : nil
102
+ if hash.nil? || hash.empty?
103
+ raise Error, "sasso-rails: config.sasso.builds must be a non-empty Hash " \
104
+ 'of { "input.scss" => "output.css" }'
105
+ end
106
+ hash
107
+ end
108
+
109
+ # Coerce + validate the style (nil/garbage gives a clear error, not a
110
+ # NoMethodError or an opaque compiler ArgumentError).
111
+ def normalize_style(style)
112
+ sym = style.to_s.to_sym
113
+ unless ALLOWED_STYLES.include?(sym)
114
+ raise Error, "sasso-rails: config.sasso.style must be one of " \
115
+ "#{ALLOWED_STYLES.inspect}, got #{style.inspect}"
116
+ end
117
+ sym
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails"
4
+ require "active_support/ordered_options"
5
+
6
+ module Sasso
7
+ module Rails
8
+ # Wires sasso into a Rails app. Configurable via `config.sasso.*`:
9
+ #
10
+ # config.sasso.builds # { "application.scss" => "application.css" }
11
+ # config.sasso.style # :expanded | :compressed (default: env-based)
12
+ # config.sasso.load_paths # extra @use/@import include dirs (Array)
13
+ # config.sasso.source_dir # default "app/assets/stylesheets"
14
+ # config.sasso.build_dir # default "app/assets/builds"
15
+ #
16
+ # The `sasso:build` rake task is enhanced onto `assets:precompile`, so the
17
+ # CSS is generated before Propshaft/Sprockets fingerprints it on deploy.
18
+ class Engine < ::Rails::Engine
19
+ config.sasso = ::ActiveSupport::OrderedOptions.new
20
+ config.sasso.builds = { "application.scss" => "application.css" }
21
+ config.sasso.style = nil # resolved in `Sasso::Rails.style_for`
22
+ config.sasso.load_paths = []
23
+ config.sasso.source_dir = "app/assets/stylesheets"
24
+ config.sasso.build_dir = "app/assets/builds"
25
+
26
+ # NOTE: no `rake_tasks do load ... end` — Rails::Engine already auto-loads
27
+ # lib/tasks/**/*.rake into the host app. Loading it again here would define
28
+ # each task (and run each `enhance`) twice.
29
+ end
30
+
31
+ module_function
32
+
33
+ # Build a Compiler from the running app's config + root.
34
+ def compiler(app = ::Rails.application)
35
+ cfg = app.config.sasso
36
+ Compiler.new(
37
+ root: app.root,
38
+ builds: cfg.builds,
39
+ style: style_for(cfg.style),
40
+ load_paths: cfg.load_paths,
41
+ source_dir: cfg.source_dir,
42
+ build_dir: cfg.build_dir,
43
+ )
44
+ end
45
+
46
+ # Default to compressed CSS in production (smaller payload), expanded
47
+ # elsewhere (readable). An explicit `config.sasso.style` always wins.
48
+ #
49
+ # If the asset pipeline has its own CSS compressor (a Sprockets app that set
50
+ # config.assets.css_compressor), stay :expanded and let the pipeline
51
+ # compress, avoiding wasteful double-minification. Propshaft sets no
52
+ # compressor, so production stays :compressed on the default Rails 8 path.
53
+ def style_for(configured)
54
+ return configured.to_sym if configured
55
+ return :expanded if pipeline_css_compressor?
56
+
57
+ ::Rails.env.production? ? :compressed : :expanded
58
+ end
59
+
60
+ def pipeline_css_compressor?
61
+ ::Rails.application&.config&.assets&.css_compressor.present?
62
+ rescue StandardError
63
+ false
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sasso
4
+ module Rails
5
+ # Versioned INDEPENDENTLY of both the `sasso` gem and the `sasso` crate.
6
+ # The gemspec pins the engine gem with a range (sasso >= 0.1.1, < 1), so a
7
+ # compiler bump does not force a lockstep release of this integration gem.
8
+ VERSION = "0.1.0"
9
+ end
10
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "sasso" # the compiler engine gem (native extension)
4
+ require "sasso/rails/version"
5
+ require "sasso/rails/compiler"
6
+
7
+ # Rails integration for the `sasso` SCSS/Sass compiler.
8
+ #
9
+ # Propshaft-first build-task model (mirrors rails/dartsass-rails): compile the
10
+ # configured entrypoints to plain CSS in `app/assets/builds/`, where the asset
11
+ # pipeline (Propshaft on Rails 8, or Sprockets serving it as a static file)
12
+ # fingerprints and serves them. Unlike dartsass-rails/tailwindcss-rails — which
13
+ # shell out to a standalone binary — this calls `Sasso.compile` IN-PROCESS via
14
+ # the native extension, so there is no subprocess, IPC, or binary-path lookup.
15
+ module Sasso
16
+ module Rails
17
+ # Loaded only inside a Rails process; the Compiler is usable standalone.
18
+ require "sasso/rails/engine" if defined?(::Rails::Railtie)
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Bundler auto-requires the gem-name file (`sasso-rails`) when an app lists
4
+ # `gem "sasso-rails"`. Delegate to the namespaced entrypoint.
5
+ require "sasso/rails"
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :sasso do
4
+ desc "Compile the configured Sass/SCSS entrypoints to app/assets/builds"
5
+ task build: :environment do
6
+ written = Sasso::Rails.compiler.build
7
+ written.each { |path| puts "sasso: compiled #{path}" }
8
+ end
9
+
10
+ desc "Watch the source stylesheets and recompile on change (Ctrl-C to stop)"
11
+ task watch: :environment do
12
+ compiler = Sasso::Rails.compiler
13
+ puts "sasso: watching #{compiler.source_dir} ..."
14
+ compiler.watch
15
+ rescue Interrupt
16
+ puts "\nsasso: stopped."
17
+ end
18
+
19
+ desc "Remove the CSS that sasso:build generated"
20
+ task clobber: :environment do
21
+ compiler = Sasso::Rails.compiler
22
+ compiler.builds.each_value do |output|
23
+ path = File.join(compiler.root, compiler.build_dir, output)
24
+ next unless File.exist?(path)
25
+
26
+ File.delete(path)
27
+ puts "sasso: removed #{path}"
28
+ end
29
+ end
30
+ end
31
+
32
+ # Generate CSS before the asset pipeline (Propshaft/Sprockets) digests it, and
33
+ # before the test DB/fixtures are prepared so system/feature tests see fresh CSS.
34
+ # Set SKIP_CSS_BUILD=1 to opt out (Docker multi-stage / separate build step).
35
+ unless ENV["SKIP_CSS_BUILD"]
36
+ if Rake::Task.task_defined?("assets:precompile")
37
+ Rake::Task["assets:precompile"].enhance(["sasso:build"])
38
+ end
39
+
40
+ # Hook whichever test-prep task this app defines (Minitest / RSpec / DB-only).
41
+ %w[test:prepare spec:prepare db:test:prepare].each do |t|
42
+ next unless Rake::Task.task_defined?(t)
43
+
44
+ Rake::Task[t].enhance(["sasso:build"])
45
+ break
46
+ end
47
+ end
48
+
49
+ # Keep `rails assets:clobber` symmetric.
50
+ if Rake::Task.task_defined?("assets:clobber")
51
+ Rake::Task["assets:clobber"].enhance(["sasso:clobber"])
52
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sasso-rails
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-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: railties
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 7.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 7.0.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.1.1
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.1.1
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '1'
47
+ description: Compiles Sass/SCSS to CSS in the Rails asset pipeline (Propshaft-first,
48
+ Sprockets-compatible) using the in-process sasso native extension — no Node.js,
49
+ no subprocess.
50
+ email:
51
+ executables: []
52
+ extensions: []
53
+ extra_rdoc_files: []
54
+ files:
55
+ - CHANGELOG.md
56
+ - LICENSE-MIT
57
+ - README.md
58
+ - lib/generators/sasso/install/install_generator.rb
59
+ - lib/generators/sasso/install/templates/application.scss
60
+ - lib/sasso-rails.rb
61
+ - lib/sasso/rails.rb
62
+ - lib/sasso/rails/compiler.rb
63
+ - lib/sasso/rails/engine.rb
64
+ - lib/sasso/rails/version.rb
65
+ - lib/tasks/sasso_tasks.rake
66
+ homepage: https://github.com/momiji-rs/sasso-rails
67
+ licenses:
68
+ - MIT
69
+ metadata:
70
+ homepage_uri: https://github.com/momiji-rs/sasso-rails
71
+ source_code_uri: https://github.com/momiji-rs/sasso-rails
72
+ changelog_uri: https://github.com/momiji-rs/sasso-rails/blob/main/CHANGELOG.md
73
+ rubygems_mfa_required: 'true'
74
+ post_install_message:
75
+ rdoc_options: []
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 3.1.0
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubygems_version: 3.5.22
90
+ signing_key:
91
+ specification_version: 4
92
+ summary: Rails integration for the sasso SCSS/Sass compiler
93
+ test_files: []