Skip to content

Instantly share code, notes, and snippets.

@ujifgc
Last active September 24, 2016 13:02
Show Gist options
  • Save ujifgc/2acaaa992b396395da71fb156beb71c8 to your computer and use it in GitHub Desktop.
Save ujifgc/2acaaa992b396395da71fb156beb71c8 to your computer and use it in GitHub Desktop.
A buggy Ruby Guard script for running reloadable zero-downtime Crystal Kemal apps
# tested on guard-2.14.0, ruby 2.3.1, Debian 8
# bugs: sometimes rb-inotify crashes on exiting guard CLI
module ::Guard
class CrystalKemal < Plugin
def initialize(options = {})
@path = options.fetch(:path, '.')
@file = options.fetch(:file, 'app.cr')
super
@app_path = File.join(@path, @file)
@app_name = File.basename(@file, '.*')
end
def start
if build
launch
else
UI.error "build of #{File.basename @new_binary} failed"
end
end
def stop
kill
end
def reload
if build
kill
launch
else
UI.error "build of #{File.basename @new_binary} failed, leaving #{File.basename @current_binary} alive"
end
end
def run_all
true
end
def run_on_change(paths)
reload
end
private
def built?
@new_binary && File.file?(@new_binary)
end
def build
build_time = Time.now.strftime('%Y%m%d-%H%M%S%L')
@new_binary = File.expand_path "#{@app_name}.#{build_time}", @path
build_command = "crystal build '#{@app_path}' -o '#{@new_binary}'"
UI.info "Building #{File.basename @new_binary}, this may take some time..."
system build_command
end
def launch
@current_pid = Process.spawn @new_binary
@current_binary = @new_binary
end
def kill
Process.kill("INT", @current_pid) if @current_pid
File.unlink(@current_binary) if @current_binary
end
end
end
# Watches your main kemal app
guard "CrystalKemal" do
watch("src/hello.cr")
# watch(%r{src/.*\.slang})
end
# Watches your sass files
guard "sass", input: "src/assets/styles", output: "public/stylesheets", style: :compressed
# Watches your es6 files
watch(/src\/assets\/scripts\/\.es6$/) { `ruby es2js.rb` }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment