Last active
December 14, 2015 23:39
-
-
Save neerolyte/5167044 to your computer and use it in GitHub Desktop.
First stab at getting guard to cleanly watch for inotify events outside of a Vagrant VM, send the event inside and report back on the outside again. See comments for more description.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'guard' | |
require 'guard/guard' | |
require 'guard/jasmine-node' | |
module ::Guard | |
class Guard | |
def vagrant_run_prefix() | |
prep_ssh_config | |
"ssh -F #{ssh_conf_file} default -- cd /vagrant\\;" | |
end | |
def stop() | |
clean_ssh_config | |
super | |
end | |
protected | |
# "vagrant ssh" is exceptionally slow, so we do some | |
# hackiness here to pull out the ssh_config from vagrant | |
# and translate it for use during our session | |
@tempdir = nil | |
def get_temp_dir() | |
if @tempdir.nil? | |
@tempdir = `mktemp -d /tmp/VagrantGuard.XXXXXX` | |
@tempdir.strip! | |
end | |
@tempdir | |
end | |
def get_ssh_config() | |
known_hosts_file = File.join(get_temp_dir, 'known_hosts') | |
conf = `vagrant ssh-config` | |
conf.gsub!(/^(\s*UserKnownHostsFile).*$/, "\\1 #{known_hosts_file}") | |
end | |
def ssh_conf_file() | |
File.join(get_temp_dir, 'ssh_config') | |
end | |
@ssh_prepped = false | |
def prep_ssh_config() | |
if ! @ssh_prepped | |
conf = get_ssh_config | |
File.open(ssh_conf_file, 'w') { |file| | |
file.write(conf) | |
} | |
@ssh_prepped = true | |
end | |
end | |
def clean_ssh_config() | |
if @ssh_prepped | |
@ssh_prepped = false | |
`rm -rf -- #{@tempdir}` | |
@tempdir = nil | |
end | |
end | |
end | |
# hack in to JasmineNode our ssh prefix | |
class VagrantJasmineNode < JasmineNode | |
def start() | |
DEFAULT_OPTIONS[:jasmine_node_bin] = | |
vagrant_run_prefix + 'node_modules/jasmine-node/bin/jasmine-node' | |
super | |
end | |
end | |
end | |
guard 'VagrantJasmineNode' do | |
watch(%r{^spec/(.+)\.spec\.js$}) { |m| "#{m[0]}" } | |
watch(%r{^lib/(.+)\.js$}) { |m| "spec/lib/#{m[1]}.spec.js" } | |
end | |
# vim: ft=ruby ts=2 sw=2 et |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What's happening:
I think feasibly this could be turned in to a plugin given a bit more love, at the moment it can be run directly as a Guardfile (but has some limitations about the parent host for now - e.g. won't work on Windows in its current form). In current form I'd obviously need to overload every Guard test driver available - but maybe there's a more general pattern for overloading them?
This method is quite different from the normal approaches I've seen people trying, including NFS mounts (not portable, difficult to set up), forcing Guard to poll (CPU intensive) and redirecting notifications from within the VM over ssh with vagrant-notify ("oh my eyes, they burn they burn!").
Keen to know if anyone can do this better.