discourse/lib/stylesheet/watcher.rb
Penar Musaraj 128fdf9d9c
DEV: Revert stylesheet refactors (#13584)
* Revert "FIX: Clear appropriate cache when updating font settings (#13582)"

This reverts commit de6cc7a924.

* Revert "DEV: Improve output of `Stylesheet::Mananger.precompile_theme_css`."

This reverts commit 95038856c9.

* Revert "FIX: Child themes being precompiled multiple times."

This reverts commit 6986b36985.

* Revert "Update spec/components/stylesheet/manager_spec.rb"

This reverts commit ddaa7cc7ea.

* Revert "Refactor scss live refreshing"

This reverts commit a838293aaf.

* Revert "Precompile core stylesheets independently of themes"

This reverts commit 99d259d39b.

* Revert "DEV: Add simple digest for core stylesheets"

This reverts commit d82c58e6cc.
2021-06-30 21:33:15 +08:00

152 lines
4.0 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# frozen_string_literal: true
require 'listen'
module Stylesheet
class Watcher
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 |plugin|
if plugin.path.to_s.include?(Rails.root.to_s)
@default_paths << File.dirname(plugin.path).sub(Rails.root.to_s, '').sub(/^\//, '')
else
# if plugin doesnt seem to be in our app, consider it as outside of the app
# and ignore it
warn("[stylesheet watcher] Ignoring outside of rails root plugin: #{plugin.path.to_s}")
end
end
@default_paths
end
def start
Thread.new do
begin
while true
worker_loop
end
rescue => e
STDERR.puts "CSS change notifier crashed \n#{e}"
start
end
end
listener_opts = { ignore: /xxxx/, only: /\.(css|scss)$/ }
listener_opts[:force_polling] = true if ENV['FORCE_POLLING']
Thread.new do
begin
plugins_paths = Dir.glob("#{Rails.root}/plugins/*").map do |file|
if File.symlink?(file)
File.expand_path(File.readlink(file), "#{Rails.root}/plugins")
else
file
end
end.compact
listener = Listen.to(*@paths, listener_opts) do |modified, added, _|
paths = [modified, added].flatten
paths.compact!
paths.map! do |long|
plugin_name = nil
plugins_paths.each do |plugin_path|
if long.include?("#{plugin_path}/")
plugin_name = File.basename(plugin_path)
break
end
end
target = nil
target_match = long.match(/admin|desktop|mobile|publish/)
if target_match&.length
target = target_match[0]
end
{
basename: File.basename(long),
target: target,
plugin_name: plugin_name
}
end
process_change(paths)
end
rescue => e
STDERR.puts "Failed to listen for CSS changes: \n#{e}"
end
listener.start
sleep
end
end
def core_assets_refresh(target)
targets = target ? [target] : ["desktop", "mobile", "admin"]
Stylesheet::Manager.clear_core_cache!(targets)
message = targets.map! do |name|
msgs = []
active_themes.each do |theme_id|
msgs << Stylesheet::Manager.new(theme_id: theme_id).stylesheet_data(name.to_sym)
end
msgs
end.flatten!
MessageBus.publish '/file-change', message
end
def plugin_assets_refresh(plugin_name, target)
Stylesheet::Manager.clear_plugin_cache!(plugin_name)
targets = []
if target.present?
targets.push("#{plugin_name}_#{target.to_s}") if DiscoursePluginRegistry.stylesheets_exists?(plugin_name, target.to_sym)
else
targets.push(plugin_name)
end
message = targets.map! do |name|
msgs = []
active_themes.each do |theme_id|
msgs << Stylesheet::Manager.new(theme_id: theme_id).stylesheet_data(name.to_sym)
end
msgs
end.flatten!
MessageBus.publish '/file-change', message
end
def worker_loop
path = @queue.pop
while @queue.length > 0
@queue.pop
end
if path[:plugin_name]
plugin_assets_refresh(path[:plugin_name], path[:target])
else
core_assets_refresh(path[:target])
end
end
def process_change(paths)
paths.each do |path|
@queue.push path
end
end
def active_themes
@active_themes ||= Theme.user_selectable.pluck(:id)
end
end
end