Example setup of development environment which enables literate programming. Needs the following gems at least in development group for it to work:
group :development do
gem 'shotgun'
gem 'org-converge'
gem 'guard'
gem 'faye-websocket'
gem 'eventmachine'
gem 'heroku'
end
Then it can be run with:
org-run this.org
[ -e ./bundle/config ] && rm ./bundle/config
bundle install
bundle exec shotgun -p 8000 -o 0.0.0.0 -s puma
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 http://localhost:8000
Tangle and reload webapp via Guard and Google Chrome devtools websocket
During development, the following is useful to tangle the file:
# -*- mode: ruby -*-
require 'org-converge'
require 'uri'
require 'net/http'
require 'eventmachine'
require 'faye/websocket'
require 'json'
WEBAPP_URL = 'localhost:8000'
CHROME_DEVTOOLS_URL = 'http://localhost:9222/json'
watch('org/app.org') do |m|
OrgConverge::Command.new({
'<org_file>' => 'org/app.org',
'--tangle' => true
}).execute!
begin
json = Net::HTTP.get(URI(CHROME_DEVTOOLS_URL))
chrome = JSON.parse(json)
rescue => e
puts "Could not retrieve debug session info from Google Chrome Dev tools: #{e}"
end
application_tab = chrome.find {|tab| tab['url'] =~ /#{WEBAPP_URL}/}
if application_tab.nil?
puts "Tab for the web app is not open at #{webapp_url}!"
return
end
websocket_debug_url = application_tab['webSocketDebuggerUrl']
# https://github.com/cyrus-and/chrome-remote-interface#chromesendmethod-params-callback
reload_tab_command = {
'id' => rand(1000),
'method' => 'Page.reload'
}.to_json
EM.run do
ws = Faye::WebSocket::Client.new(websocket_debug_url)
ws.onopen = lambda do |event|
puts "Reloading application via debug websocket running at #{ws.url}..."
ws.send(reload_tab_command)
end
ws.onmessage = lambda do |event|
event_info = JSON.parse(event.data)
if event_info['error']
puts "Could not reload application: #{event_info['error']}"
else
puts "Done reloading application!"
end
EM.stop
end
end
end
interactor :off
bundle exec guard