Last active
August 29, 2015 14:09
-
-
Save boof/1e670391787744d4ed3b to your computer and use it in GitHub Desktop.
Sync back files from a vagrant guest (rsync shared folders).
This file contains 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
#!/usr/bin/env ruby | |
# Usage: bin/rsync-back [--dry-run] [pattern ...] | |
require 'fileutils' | |
require 'tmpdir' | |
options = { | |
user: 'vagrant', | |
host: 'localhost', | |
directory: '/vagrant/', | |
args: %w[ | |
--archive --keep-dirlinks --links | |
--chmod=ugo=rwX --no-perms --no-owner --no-group | |
], | |
# add this file to your excludes list | |
exclude_from: 'rsync.excludes', | |
transport: 'rsync', | |
ssh: { | |
port: 2222, | |
key_file: "#{ ENV['HOME'] }/.vagrant.d/insecure_private_key", | |
options: %w[ | |
StrictHostKeyChecking=no | |
UserKnownHostsFile=/dev/null | |
] | |
}, | |
rsync: { | |
port: 8873 | |
} | |
} | |
root = File.expand_path '..', __FILE__ | |
root = File.dirname root until File.directory? "#{ root }/.git" or root == '/' | |
abort if root == '/' | |
ROOT = root | |
options[:exclude_from] = File.expand_path options[:exclude_from], ROOT | |
def sync(src, dest, opts) | |
args = opts[:args] + [%Q'--exclude-from="#{ opts[:exclude_from] }"'] | |
cmd = format 'rsync %s %s %s', args * ' ', src, dest | |
puts ">> #{ cmd }" | |
system cmd | |
end | |
def uri(options, scheme = '', port = '') | |
format '%s%s@%s:%s%s', scheme, options[:user], options[:host], | |
port, options[:directory] | |
end | |
def sync_over_rsync(destination, options) | |
src = uri(options, 'rsync://', options[:rsync][:port]) | |
sync src, destination, options | |
end | |
def sync_over_ssh(destination, options) | |
ssh_config = options[:ssh] | |
ssh_args = ssh_config[:options].map { |o| "-o #{ o }" } | |
ssh_args << format('-p %i', ssh_config[:port]) | |
ssh_args << format(%q"-i '%s'", ssh_config[:key_file]) | |
options[:args] << format('--rsh="ssh %s"', ssh_args * ' ') | |
sync uri(options), destination, options | |
end | |
def rsync(destination, options) | |
send "sync_over_#{ options[:transport] }", destination, options | |
end | |
Dir.mktmpdir do |tmp| | |
rsync(tmp, options) or abort | |
noop =! ARGV.reject! { |arg| arg == '--dry-run' }.nil? | |
puts 'Not doing anything, actually.' if noop | |
excludes = File.readlines(options[:exclude_from]).each(&:chomp!) | |
includes = ARGV.empty? ? %w[*] : ARGV | |
# system "diff --brief --recursive --exclude-from=#{ excludes_from } #{ tmp } #{ root }" | |
`git --work-tree #{ tmp } status --porcelain`.chomp.each_line do |line| | |
path = line[3..-1].chomp | |
if excludes.any? { |pattern| File.fnmatch pattern, path } | |
puts " E #{ path }" | |
next | |
end | |
unless includes.any? { |pattern| File.fnmatch pattern, path } | |
puts " I #{ path }" | |
next | |
end | |
source = "#{ tmp }/#{ path }" | |
destination = File.join root, | |
path !~ %r'/$' ? path : [ File.dirname(path), '' ] | |
case line | |
when /^(?: M) / # file modified | |
FileUtils.cp_r source, destination, noop: noop | |
puts line | |
when /^(?: A|\?\?) / # file added | |
FileUtils.cp_r source, destination, noop: noop | |
puts line | |
when /^(?: D) / # file deleted | |
FileUtils.rm_r destination, noop: true, verbose: true | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment