Files
homebrew-tap/scripts/file_watcher.rb

124 lines
3.1 KiB
Ruby

# typed: strict
# frozen_string_literal: true
# Module for handling file watching and change detection.
# Classes including this module must define a `build_site` method.
module FileWatcher
def start_file_watcher
Thread.new do
last_mtime = max_mtime
rebuild_pending = false
watched_files = watched_files_count
puts "👀 Watching #{watched_files} files for changes..."
loop do
sleep 1
current_mtime = max_mtime
next if should_skip_rebuild?(current_mtime, last_mtime, rebuild_pending)
rebuild_pending = true
handle_file_change(last_mtime)
last_mtime = perform_rebuild_with_debounce
rebuild_pending = false
puts "✅ Rebuild complete"
rescue => e
puts "⚠️ File watcher error: #{e.message}"
puts "📍 Backtrace: #{e.backtrace.first(3).join(", ")}"
rebuild_pending = false
sleep 2
puts "🔄 File watcher continuing..."
end
end
end
def watched_files_count
all_watched_files.count { |file| !File.directory?(file) }
end
def find_changed_file(since_mtime)
all_watched_files.find do |file|
File.exist?(file) && !File.directory?(file) && File.mtime(file) > since_mtime
end
end
def all_watched_files
[
formula_files,
theme_files,
template_files,
style_and_script_files,
asset_files,
build_script_files,
config_files,
].flatten.compact.uniq
end
def max_mtime
all_watched_files
.select { |file| File.exist?(file) && !File.directory?(file) }
.map { |file| File.mtime(file) }
.max || Time.at(0)
end
private
def should_skip_rebuild?(current_mtime, last_mtime, rebuild_pending)
current_mtime <= last_mtime || rebuild_pending
end
def handle_file_change(last_mtime)
changed_file = find_changed_file(last_mtime)
puts "📝 Changed: #{changed_file}" if changed_file
puts "🔄 Rebuilding in 1 second..."
end
def perform_rebuild_with_debounce
sleep 1 # Debounce: wait for additional changes
final_mtime = max_mtime
puts "🔨 Building site..."
build_site
final_mtime
end
def formula_files
Dir.glob(File.expand_path("../Formula/**/*.rb", __dir__))
end
def theme_files
Dir.glob(File.expand_path("../theme/**/*", __dir__))
end
def template_files
[
Dir.glob(File.expand_path("../theme/*.erb", __dir__)),
Dir.glob(File.expand_path("../theme/_*.erb", __dir__)),
Dir.glob(File.expand_path("../theme/*.html.erb", __dir__)),
Dir.glob(File.expand_path("../theme/_*.html.erb", __dir__)),
].flatten
end
def style_and_script_files
[
Dir.glob(File.expand_path("../theme/*.css", __dir__)),
Dir.glob(File.expand_path("../theme/*.js", __dir__)),
].flatten
end
def asset_files
Dir.glob(File.expand_path("../theme/assets/**/*", __dir__))
end
def build_script_files
[
File.expand_path("../scripts/parse_formulas.rb", __dir__),
File.expand_path("../scripts/build_site.rb", __dir__),
]
end
def config_files
[File.expand_path("../Makefile", __dir__)]
end
end