Created
April 20, 2012 05:57
-
-
Save lox/2426455 to your computer and use it in GitHub Desktop.
Revisions
-
lox created this gist
Apr 20, 2012 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,87 @@ #!/usr/bin/env ruby require 'rubygems' require 'rb-fsevent' require 'optparse' require 'net/ssh' require 'net/sftp' def watch_directory(sftp, watch_dir, target_dir) fsevent = FSEvent.new fsevent.watch [watch_dir] do |directories| directories.each do |dir| unless dir.include? ".git" sync_directory sftp, dir, dir.gsub(watch_dir, target_dir) end end end fsevent.run end def sync_directory(sftp, local_dir, remote_dir) remote_files = {} # collect remote mtimes sftp.dir.foreach remote_dir do |f| remote_files[f.name] = f.attributes.mtime end # check local mtimes Dir.foreach(local_dir) do |local_file| f = "#{local_dir}#{local_file}" if File.file?(f) and (!remote_files.key? local_file or remote_files[local_file] < File.mtime(f).to_i) print "#{f} changed, sending... " timer = Time.now begin sftp.upload! f, "#{remote_dir}#{local_file}" puts " done in #{(Time.now - timer)*1000}ms" rescue Exception => e puts " failed! #{e.message}" end end end end options = { :verbose=>false, :git=>false } OptionParser.new do |opts| opts.banner = "Usage: watch.rb user@host:path [options]" opts.on("-v", "--[no-]verbose", "Run verbosely") do |v| options[:verbose] = v end opts.on("-g", "--git", "Sync the remote side to the current git HEAD") do |g| options[:git] = g end end.parse! remote_user = ARGV[0].split('@').first remote_host = ARGV[0].split('@').last.split(':').first watch_dir = File.expand_path(ARGV[0].split('@').last.split(':').last) remote_dir = "/home/#{remote_user}/"+File.basename(watch_dir) Net::SSH.start(remote_host, remote_user) do |session| if options[:git] branch = `cd #{watch_dir}; git name-rev --name-only HEAD`.chomp sha1 = `cd #{watch_dir}; git rev-parse HEAD`.chomp puts "Cleaning remote repo" session.exec! "git clean -d #{remote_dir}" puts "Synchronizing remote to #{branch}@#{sha1}" ["git fetch", "git checkout #{branch}", "git reset --hard #{sha1}", "git submodule update --init"].each do |c| session.exec! "cd #{remote_dir}; #{c}" end puts "Sending changed files from local repo" puts `cd #{watch_dir}; git status -s -u --ignore-submodules`.chomp end puts "Listening for changes in #{watch_dir}" watch_directory session.sftp, watch_dir, remote_dir end