Class: Sasso::Rails::Compiler

Inherits:
Object
  • Object
show all
Defined in:
lib/sasso/rails/compiler.rb

Overview

Compiles configured Sass/SCSS entrypoints to plain CSS files under the builds directory. Deliberately Rails-free so it can be unit-tested with a plain temp ‘root:` — the Engine just wires `Rails.root` and config in.

Sasso::Rails::Compiler.new(
  root:       Rails.root,
  builds:     { "application.scss" => "application.css" },
  style:      :expanded,
  load_paths: [],            # extra dirs, in addition to the source dir
  source_dir: "app/assets/stylesheets",
  build_dir:  "app/assets/builds",
).build

Constant Summary collapse

Error =
Class.new(StandardError)
ALLOWED_STYLES =
%i[expanded compressed].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root:, builds:, style: :expanded, load_paths: [], source_dir: "app/assets/stylesheets", build_dir: "app/assets/builds") ⇒ Compiler

Returns a new instance of Compiler.



26
27
28
29
30
31
32
33
34
35
# File 'lib/sasso/rails/compiler.rb', line 26

def initialize(root:, builds:, style: :expanded, load_paths: [],
               source_dir: "app/assets/stylesheets",
               build_dir: "app/assets/builds")
  @root       = File.expand_path(root.to_s)
  @builds     = normalize_builds(builds)
  @style      = normalize_style(style)
  @load_paths = Array(load_paths).map(&:to_s)
  @source_dir = source_dir.to_s
  @build_dir  = build_dir.to_s
end

Instance Attribute Details

#build_dirObject (readonly)

Returns the value of attribute build_dir.



24
25
26
# File 'lib/sasso/rails/compiler.rb', line 24

def build_dir
  @build_dir
end

#buildsObject (readonly)

Returns the value of attribute builds.



24
25
26
# File 'lib/sasso/rails/compiler.rb', line 24

def builds
  @builds
end

#load_pathsObject (readonly)

Returns the value of attribute load_paths.



24
25
26
# File 'lib/sasso/rails/compiler.rb', line 24

def load_paths
  @load_paths
end

#rootObject (readonly)

Returns the value of attribute root.



24
25
26
# File 'lib/sasso/rails/compiler.rb', line 24

def root
  @root
end

#source_dirObject (readonly)

Returns the value of attribute source_dir.



24
25
26
# File 'lib/sasso/rails/compiler.rb', line 24

def source_dir
  @source_dir
end

#styleObject (readonly)

Returns the value of attribute style.



24
25
26
# File 'lib/sasso/rails/compiler.rb', line 24

def style
  @style
end

Instance Method Details

#buildObject

Compile every entrypoint; returns the list of written output paths.



38
39
40
# File 'lib/sasso/rails/compiler.rb', line 38

def build
  builds.map { |input, output| build_one(input, output) }
end

#build_one(input, output) ⇒ Object

Compile a single ‘input` (relative to source_dir) to `output` (relative to build_dir), returning the absolute path written.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/sasso/rails/compiler.rb', line 44

def build_one(input, output)
  src = File.join(@root, @source_dir, input)
  unless File.file?(src)
    raise Error, "sasso-rails: input stylesheet not found: #{src}"
  end

  # `Sasso.compile` already searches the entry file's own directory first
  # (for sibling @use/@import); pass any extra include dirs after it.
  css = ::Sasso.compile(src, style: @style, load_paths: @load_paths)

  dest = File.join(@root, @build_dir, output)
  FileUtils.mkdir_p(File.dirname(dest))
  File.write(dest, css)
  dest
end

#watch(interval: 1.0) ⇒ Object

Recompile whenever a watched source file changes. Dependency-free poll loop (no ‘listen` gem): cheap mtime scan of the source + load_path trees. Blocks. A compile error (including on the FIRST pass) is reported and the loop keeps running — the watcher must survive a mid-edit broken file.



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/sasso/rails/compiler.rb', line 64

def watch(interval: 1.0)
  safe_build
  snapshot = source_mtimes
  loop do
    sleep interval
    current = source_mtimes
    next if current == snapshot

    snapshot = current
    safe_build
  end
end