Skip to content

Instantly share code, notes, and snippets.

@dymk
Created January 23, 2017 23:12
Show Gist options
  • Select an option

  • Save dymk/38da7c95063f0128e894287e2211670c to your computer and use it in GitHub Desktop.

Select an option

Save dymk/38da7c95063f0128e894287e2211670c to your computer and use it in GitHub Desktop.
Pretty generic project watcher for developing locally, and verifying compilation/tests on a remote server (made for UCSD CSE124)
# dependencies:
#gem install filewatcher
#gem install childprocess
#gem install net-sftp
# usage: ruby project_watcher.rb <user>@<server> <project or hw folder>
# e.g. ruby project_watcher.rb cse124XYZ@ieng6.ucsd.edu project1/
# you probably want to add the following to your .gitignore
# as well:
# *.o-*
# *.obj
# *.dSYM
# *.dSYM/*
# /httpd
require 'filewatcher'
require 'childprocess'
require 'net/sftp'
folder = ARGV[1]
if folder && File.exist?(folder)
if folder[-1] == '/'
folder = folder[0...-1]
end
puts "watching folder #{folder}"
else
puts "folder #{folder} does not exist!"
puts "usage: watcher.rb <user> <folder>"
exit 1
end
server = if ARGV[0]
ARGV[0]
else
puts "no user specified"
puts "usage: watcher.rb <user> <folder>"
exit 1
end
ignore_file = File.join(folder, '.gitignore')
ignores = if File.exist?(ignore_file)
File.read(ignore_file).split("\n").map(&:strip).reject {|i|
i[0] == '#' || i.empty?
}
else
[]
end
puts "ignore list: #{ignores.join(", ")}"
user, host = server.split("@")
sftp_conn = begin
puts "connect -> #{host} (#{user})"
Net::SFTP.start(host, user)
end
# hush announcement (screws up bash login shell with no tty)
# `rm ~/.hushlogin` to get announcement back
puts `ssh #{server} touch ~#{user}/.hushlogin`
# initial rsync to verify both sides are the same
begin
rs = ChildProcess.build("rsync", "-avP", folder, server)
rs.io.inherit!
rs.start
rs.wait
end
FileWatcher.new(folder).watch do |filename|
puts "#{filename} changed"
filename_nofolder = filename[folder.length..-1]
if i = ignores.find { |i|
# puts "#{i} -> #{filename_nofolder} ";
File.fnmatch(i, filename_nofolder)
}
puts "ignoring #{filename} (#{i})"
next
end
path = filename
puts "upload #{path} -> #{server}:#{path}"
sftp_conn.upload!(path, path)
cp = ChildProcess.build("ssh", server, "sh", "--login", "-c", "'make -C #{folder}'")
cp.io.inherit!
cp.start
cp.wait
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment