discourse/lib/stylesheet/watcher.rb
Sam Saffron 30990006a9 DEV: enable frozen string literal on all files
This reduces chances of errors where consumers of strings mutate inputs
and reduces memory usage of the app.

Test suite passes now, but there may be some stuff left, so we will run
a few sites on a branch prior to merging
2019-05-13 09:31:32 +08:00

97 lines
2.1 KiB
Ruby

# frozen_string_literal: true
require 'listen'
module Stylesheet
class Watcher
REDIS_KEY = "dev_last_used_theme_id"
def self.theme_id=(v)
$redis.set(REDIS_KEY, v)
end
def self.theme_id
($redis.get(REDIS_KEY) || SiteSetting.default_theme_id).to_i
end
def self.watch(paths = nil)
watcher = new(paths)
watcher.start
watcher
end
def initialize(paths)
@paths = paths || Watcher.default_paths
@queue = Queue.new
end
def self.default_paths
return @default_paths if @default_paths
@default_paths = ["app/assets/stylesheets"]
Discourse.plugins.each do |p|
@default_paths << File.dirname(p.path).sub(Rails.root.to_s, '').sub(/^\//, '')
end
@default_paths
end
def start
Thread.new do
begin
while true
worker_loop
end
rescue => e
STDERR.puts "CSS change notifier crashed #{e}"
end
end
root = Rails.root.to_s
listener_opts = { ignore: /xxxx/ }
listener_opts[:force_polling] = true if ENV['FORCE_POLLING']
@paths.each do |watch|
Thread.new do
begin
listener = Listen.to("#{root}/#{watch}", listener_opts) do |modified, added, _|
paths = [modified, added].flatten
paths.compact!
paths.map! { |long| long[(root.length + 1)..-1] }
process_change(paths)
end
rescue => e
STDERR.puts "Failed to listen for CSS changes at: #{watch}\n#{e}"
end
listener.start
sleep
end
end
end
def worker_loop
@queue.pop
while @queue.length > 0
@queue.pop
end
Stylesheet::Manager.cache.clear
message = ["desktop", "mobile", "admin"].map do |name|
Stylesheet::Manager.stylesheet_data(name.to_sym, Stylesheet::Watcher.theme_id)
end.flatten
MessageBus.publish '/file-change', message
end
def process_change(paths)
paths.each do |path|
if path =~ /\.(css|scss)$/
@queue.push path
end
end
end
end
end