vagrant-unison2 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 791a0762a750b543db7353353134c51b89ec51df
4
+ data.tar.gz: b6b30f336b4742305440f39787a833afec57f1b2
5
+ SHA512:
6
+ metadata.gz: 950b0d2754cf186002ea64244734082196b4aa11513301d18b53a0d6b209d24e353f315068de3d34cfa880c73d510a5349c2e164fc1e459a73fc062e2284320c
7
+ data.tar.gz: 5dde828e8acd191a92c0b655d99e21e7bd48e26ed84be0ea74018ef0974136901ca0a8e4bc86f81cf98cba525f4653b4fc6692f73885eee0bc456452c1a38e55
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ # OS-specific
2
+ .DS_Store
3
+
4
+ # Bundler/Rubygems
5
+ *.gem
6
+ .bundle
7
+ pkg/*
8
+ tags
9
+ Gemfile.lock
10
+
11
+ # Vagrant
12
+ .vagrant
13
+ Vagrantfile
14
+ !example_box/Vagrantfile
15
+
16
+ # IDEs
17
+ .project
18
+ .idea
data/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # 1.0.0 (Jan 2016)
2
+
3
+ * Breaking commit on dcosson fork
4
+ * Renames all of the `vagrant ___` commands to start with `unison`, e.g. `vagrant-unison-sync`
5
+ * Adds a command to sync once and exit, `vagrant unison-sync-once`
6
+ * Fix bug where cleanup tried to delete `~/.unison` as root, which resolved to wrong thing (at least in Virtualbox) and failed silently bc what we want to delete is `/home/vagrant/.unison`
7
+ * Pin to newer syntax of the listen gem and stop using a method that had been renamed.
8
+
9
+ # 0.0.17 (Jan 2016)
10
+
11
+ * Fix bug in validation. Previously, you couldn't run vagrant on a Vagrantfile that didn't use vagrant-unison if you had the plugin installed, because all the config args were required.
12
+
13
+ # 0.1.0 (March 2013)
14
+
15
+ * Initial release.
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ # We depend on Vagrant for development, but we don't add it as a
7
+ # gem dependency because we expect to be installed within the
8
+ # Vagrant environment itself using `vagrant plugin`.
9
+ gem "vagrant", :git => "git://github.com/mitchellh/vagrant.git"
10
+ end
data/LICENSE ADDED
@@ -0,0 +1,8 @@
1
+ The MIT License (MIT)
2
+ Copyright (c) 2013 Mitchell Hashimoto
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5
+
6
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7
+
8
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # Vagrant Unison Plugin
2
+
3
+ This is a [Vagrant](http://www.vagrantup.com) 1.1+ plugin that syncs files over SSH from a local folder
4
+ to your Vagrant VM (local or on AWS). Under the covers it uses [Unison](http://www.cis.upenn.edu/~bcpierce/unison/)
5
+
6
+ **NOTE:** This plugin requires Vagrant 1.1+,
7
+
8
+ ## Features
9
+
10
+ * Unisoned folder support via `unison` over `ssh` -> will work with any vagrant provider, eg Virtualbox or AWS.
11
+
12
+ ## Usage
13
+
14
+ 1. You must already have [Unison](http://www.cis.upenn.edu/~bcpierce/unison/) installed and in your path.
15
+ * On Mac you can install this with Homebrew: `brew install unison` (on Yosemite you will have to use https://rudix-mountainlion.googlecode.com/files/unison-2.40.102-0.pkg)
16
+ * On Unix (Ubuntu) install using `sudo apt-get install unison`
17
+ * On Windows, download [2.40.102](http://alan.petitepomme.net/unison/assets/Unison-2.40.102.zip), unzip, rename `Unison-2.40.102 Text.exe` to `unison.exe` and copy to somewhere in your path.
18
+ 1. Install using standard Vagrant 1.1+ plugin installation methods.
19
+ ```
20
+ $ vagrant plugin install vagrant-unison
21
+ ```
22
+ 1. After installing, edit your Vagrantfile and add a configuration directive similar to the below:
23
+ ```
24
+ Vagrant.configure("2") do |config|
25
+ config.vm.box = "dummy"
26
+
27
+ config.unison.host_folder = "src/" #relative to the folder your Vagrantfile is in
28
+ config.unison.guest_folder = "src/" #relative to the vagrant home folder -> /home/vagrant
29
+ config.unison.ignore = "Name {.DS_Store,.git,node_modules}"
30
+
31
+ end
32
+ ```
33
+ 1. Start up your starting your vagrant box as normal (eg: `vagrant up`)
34
+
35
+ ## Start syncing Folders
36
+
37
+ Run `vagrant unison-sync-once` to run a single, non-interactive sync and then exit.
38
+
39
+ Run `vagrant unison-sync` to sync then start watching the local_folder for changes, and syncing these to your vagrang VM.
40
+
41
+ Under the covers this uses your system installation of [Unison](http://www.cis.upenn.edu/~bcpierce/unison/),
42
+ which must be installed in your path.
43
+
44
+ ## Start syncing Folders with polling (unison repeat mode)
45
+
46
+ Run `vagrant unison-sync-polling` to start in bidirect monitor (repeat) mode - every second unison checks for changes on either side and syncs them.
47
+
48
+ ## Sync in interactive mode
49
+
50
+ Run `vagrant unison-sync-interactive` to start in interactive mode. The first time
51
+ it will ask what to do for every top-level file & directory, otherwise is asks
52
+ about changes. It allows solving conflicts in various ways. Press "?" in
53
+ interactive mode to see options for resolving.
54
+
55
+ This is a useful tool when the automatic sync sees a change in a file on both
56
+ sides and skips it.
57
+
58
+ ## Cleanup unison database
59
+ When you get
60
+ ```
61
+ Fatal error: Warning: inconsistent state.
62
+ The archive file is missing on some hosts.
63
+ For safety, the remaining copies should be deleted.
64
+ Archive arb126d8de1ef26a835b94cf51975c530f on host blablabla.local should be DELETED
65
+ Archive arbc6a36f85b3d1473c55565dd220acf68 on host blablabla is MISSING
66
+ Please delete archive files as appropriate and try again
67
+ or invoke Unison with -ignorearchives flag.
68
+ ```
69
+
70
+ Run `vagrant unison-cleanup` to clear Archive from ~/Library/Application Support/Unison/ and files from host folder.
71
+ Running Unison with -ignorearchives flag is a bad idea, since it will produce conflicts.
72
+
73
+ ## Development
74
+
75
+ To work on the `vagrant-unison` plugin, clone this repository out, and use
76
+ [Bundler](http://gembundler.com) to get the dependencies:
77
+
78
+ ```
79
+ $ bundle
80
+ ```
81
+
82
+ Once you have the dependencies, verify the unit tests pass with `rake`:
83
+
84
+ ```
85
+ $ bundle exec rake
86
+ ```
87
+
88
+ If those pass, you're ready to start developing the plugin. You can test
89
+ the plugin without installing it into your Vagrant environment by just
90
+ creating a `Vagrantfile` in the top level of this directory (it is gitignored)
91
+ that uses it, and uses bundler to execute Vagrant:
92
+
93
+ ```
94
+ $ bundle exec vagrant up
95
+ $ bundle exec vagrant unison-sync
96
+ ```
97
+
98
+ Or, install the plugin from your local build to use with an existing project's
99
+ Vagrantfile on your machine.
100
+
101
+ Build the plugin with
102
+
103
+ ```
104
+ rake build
105
+ ```
106
+
107
+ Now you'll see the built gem in a pkg directory. Install it with
108
+
109
+ ```
110
+ vagrant plugin install pkg/vagrant-unison-VERSION.gem
111
+ ```
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'rspec/core/rake_task'
4
+
5
+ # Immediately sync all stdout so that tools like buildbot can
6
+ # immediately load in the output.
7
+ $stdout.sync = true
8
+ $stderr.sync = true
9
+
10
+ # Change to the directory of this file.
11
+ Dir.chdir(File.expand_path("../", __FILE__))
12
+
13
+ # This installs the tasks that help with gem creation and
14
+ # publishing.
15
+ Bundler::GemHelper.install_tasks
16
+
17
+ # Install the `spec` task so that we can run tests.
18
+ RSpec::Core::RakeTask.new
19
+
20
+ # Default task is to run the unit tests
21
+ task :default => "spec"
@@ -0,0 +1,163 @@
1
+ require "log4r"
2
+ require "vagrant"
3
+ require "thread"
4
+ require 'listen'
5
+
6
+ require_relative 'unison_paths'
7
+ require_relative 'ssh_command'
8
+ require_relative 'shell_command'
9
+ require_relative 'unison_sync'
10
+
11
+ module VagrantPlugins
12
+ module Unison
13
+ class Command < Vagrant.plugin("2", :command)
14
+ include UnisonSync
15
+
16
+ def execute
17
+ with_target_vms do |machine|
18
+ paths = UnisonPaths.new(@env, machine)
19
+ host_path = paths.host
20
+
21
+ sync(machine, paths)
22
+
23
+ @env.ui.info "Watching #{host_path} for changes..."
24
+
25
+ listener = Listen.to(host_path) do |modified, added, removed|
26
+ @env.ui.info "Detected modifications to #{modified.inspect}" unless modified.empty?
27
+ @env.ui.info "Detected new files #{added.inspect}" unless added.empty?
28
+ @env.ui.info "Detected deleted files #{removed.inspect}" unless removed.empty?
29
+
30
+ sync(machine, paths)
31
+ end
32
+
33
+ queue = Queue.new
34
+
35
+ callback = lambda do
36
+ # This needs to execute in another thread because Thread
37
+ # synchronization can't happen in a trap context.
38
+ Thread.new { queue << true }
39
+ end
40
+
41
+ # Run the listener in a busy block so that we can cleanly
42
+ # exit once we receive an interrupt.
43
+ Vagrant::Util::Busy.busy(callback) do
44
+ listener.start
45
+ queue.pop
46
+ listener.stop if listener.paused? || listener.processing?
47
+ end
48
+ end
49
+
50
+ 0
51
+ end
52
+
53
+ def sync(machine, paths)
54
+ execute_sync_command(machine) do |command|
55
+ command.batch = true
56
+
57
+ @env.ui.info "Running #{command.to_s}"
58
+
59
+ r = Vagrant::Util::Subprocess.execute(*command.to_a)
60
+
61
+ case r.exit_code
62
+ when 0
63
+ @env.ui.info "Unison completed succesfully"
64
+ when 1
65
+ @env.ui.info "Unison completed - all file transfers were successful; some files were skipped"
66
+ when 2
67
+ @env.ui.info "Unison completed - non-fatal failures during file transfer: #{r.stderr}"
68
+ else
69
+ raise Vagrant::Errors::UnisonError,
70
+ :command => command.to_s,
71
+ :guestpath => paths.guest,
72
+ :hostpath => paths.host,
73
+ :stderr => r.stderr
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ class CommandOnce < Vagrant.plugin("2", :command)
80
+ include UnisonSync
81
+
82
+ def execute
83
+ with_target_vms do |machine|
84
+ execute_sync_command(machine) do |command|
85
+ command.batch = true
86
+ command.terse = true
87
+ command = command.to_s
88
+
89
+ @env.ui.info "Running unison once"
90
+ @env.ui.info " #{command}"
91
+
92
+ system(command)
93
+ end
94
+ end
95
+
96
+ 0
97
+ end
98
+ end
99
+
100
+ class CommandPolling < Vagrant.plugin("2", :command)
101
+ include UnisonSync
102
+
103
+ def execute
104
+ with_target_vms do |machine|
105
+ execute_sync_command(machine) do |command|
106
+ command.repeat = true
107
+ command.terse = true
108
+ command = command.to_s
109
+
110
+ @env.ui.info "Running #{command}"
111
+
112
+ system(command)
113
+ end
114
+ end
115
+
116
+ 0
117
+ end
118
+ end
119
+
120
+ class CommandCleanup < Vagrant.plugin("2", :command)
121
+ include UnisonSync
122
+
123
+ def execute
124
+ with_target_vms do |machine|
125
+ guest_path = UnisonPaths.new(@env, machine).guest
126
+
127
+ command = "rm -rf ~/Library/'Application Support'/Unison/*"
128
+ @env.ui.info "Running #{command} on host"
129
+ system(command)
130
+
131
+ command = "rm -rf #{guest_path}"
132
+ @env.ui.info "Running #{command} on guest VM"
133
+ machine.communicate.sudo(command)
134
+
135
+ command = "rm -rf ~/.unison"
136
+ @env.ui.info "Running #{command} on guest VM"
137
+ machine.communicate.execute(command)
138
+ end
139
+
140
+ 0
141
+ end
142
+ end
143
+
144
+ class CommandInteract < Vagrant.plugin("2", :command)
145
+ include UnisonSync
146
+
147
+ def execute
148
+ with_target_vms do |machine|
149
+ execute_sync_command(machine) do |command|
150
+ command.terse = true
151
+ command = command.to_s
152
+
153
+ @env.ui.info "Running #{command}"
154
+
155
+ system(command)
156
+ end
157
+ end
158
+
159
+ 0
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,68 @@
1
+ require "vagrant"
2
+
3
+ module VagrantPlugins
4
+ module Unison
5
+ class Config < Vagrant.plugin("2", :config)
6
+ # Host Folder to Sync
7
+ #
8
+ # @return [String]
9
+ attr_accessor :host_folder
10
+
11
+ # Guest Folder to Sync.
12
+ #
13
+ # @return [String]
14
+ attr_accessor :guest_folder
15
+
16
+ # Pattern of files to ignore.
17
+ #
18
+ # @return [String]
19
+ attr_accessor :ignore
20
+
21
+ # Repeat speed.
22
+ #
23
+ # @return [String]
24
+ attr_accessor :repeat
25
+
26
+ def initialize(region_specific=false)
27
+ @host_folder = UNSET_VALUE
28
+ @remote_folder = UNSET_VALUE
29
+ @ignore = UNSET_VALUE
30
+ @repeat = UNSET_VALUE
31
+ end
32
+
33
+ #-------------------------------------------------------------------
34
+ # Internal methods.
35
+ #-------------------------------------------------------------------
36
+
37
+ # def merge(other)
38
+ # super.tap do |result|
39
+ # # TODO - do something sensible; current last config wins
40
+ # result.local_folder = other.local_folder
41
+ # result.remote_folder = other.remote_folder
42
+ # end
43
+ # end
44
+
45
+ def finalize!
46
+ # The access keys default to nil
47
+ @host_folder = nil if @host_folder == UNSET_VALUE
48
+ @guest_folder = nil if @guest_folder == UNSET_VALUE
49
+ @ignore = nil if @ignore == UNSET_VALUE
50
+ @repeat = 1 if @repeat == UNSET_VALUE
51
+
52
+ # Mark that we finalized
53
+ @__finalized = true
54
+ end
55
+
56
+ def validate(machine)
57
+ errors = []
58
+
59
+ if !(@host_folder.nil? && @guest_folder.nil?)
60
+ errors << I18n.t("vagrant_unison.config.unison_host_folder_required") if @host_folder.nil?
61
+ errors << I18n.t("vagrant_unison.config.unison_guest_folder_required") if @guest_folder.nil?
62
+ end
63
+
64
+ { "Unison" => errors }
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,9 @@
1
+ require "vagrant"
2
+
3
+ module Vagrant
4
+ module Errors
5
+ class UnisonError < VagrantError
6
+ error_key(:unison_error, "vagrant_unison.errors")
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,113 @@
1
+ begin
2
+ require "vagrant"
3
+ rescue LoadError
4
+ raise "The vagrant-unison plugin must be run within Vagrant."
5
+ end
6
+
7
+ # This is a sanity check to make sure no one is attempting to install
8
+ # this into an early Vagrant version.
9
+ if Vagrant::VERSION < "1.1.0"
10
+ raise "The vagrant-unison plugin is only compatible with Vagrant 1.1+"
11
+ end
12
+
13
+ module VagrantPlugins
14
+ module Unison
15
+ class Plugin < Vagrant.plugin("2")
16
+ name "Unison"
17
+ description <<-DESC
18
+ This plugin syncs files over SSH from a local folder
19
+ to your Vagrant VM (local or on AWS).
20
+ DESC
21
+
22
+ config "unison" do
23
+ require_relative "config"
24
+ Config
25
+ end
26
+
27
+ command "unison-sync" do
28
+ # Setup logging and i18n
29
+ setup_logging
30
+ setup_i18n
31
+
32
+ #Return the command
33
+ require_relative "command"
34
+ Command
35
+ end
36
+
37
+ command "unison-sync-once" do
38
+ setup_logging
39
+ setup_i18n
40
+
41
+ #Return the command
42
+ require_relative "command"
43
+ CommandOnce
44
+ end
45
+
46
+ command "unison-sync-interact" do
47
+ # Setup logging and i18n
48
+ setup_logging
49
+ setup_i18n
50
+
51
+ #Return the command
52
+ require_relative "command"
53
+ CommandInteract
54
+ end
55
+
56
+
57
+ command "unison-sync-polling" do
58
+ # Setup logging and i18n
59
+ setup_logging
60
+ setup_i18n
61
+
62
+ #Return the command
63
+ require_relative "command"
64
+ CommandPolling
65
+ end
66
+
67
+ command "unison-cleanup" do
68
+ # Setup logging and i18n
69
+ setup_logging
70
+ setup_i18n
71
+
72
+ #Return the command
73
+ require_relative "command"
74
+ CommandCleanup
75
+ end
76
+
77
+ # This initializes the internationalization strings.
78
+ def self.setup_i18n
79
+ I18n.load_path << File.expand_path("locales/en.yml", Unison.source_root)
80
+ I18n.reload!
81
+ end
82
+
83
+ # This sets up our log level to be whatever VAGRANT_LOG is.
84
+ def self.setup_logging
85
+ require "log4r"
86
+
87
+ level = nil
88
+ begin
89
+ level = Log4r.const_get(ENV["VAGRANT_LOG"].upcase)
90
+ rescue NameError
91
+ # This means that the logging constant wasn't found,
92
+ # which is fine. We just keep `level` as `nil`. But
93
+ # we tell the user.
94
+ level = nil
95
+ end
96
+
97
+ # Some constants, such as "true" resolve to booleans, so the
98
+ # above error checking doesn't catch it. This will check to make
99
+ # sure that the log level is an integer, as Log4r requires.
100
+ level = nil if !level.is_a?(Integer)
101
+
102
+ # Set the logging level on all "vagrant" namespaced
103
+ # logs as long as we have a valid level.
104
+ if level
105
+ logger = Log4r::Logger.new("vagrant_unison")
106
+ logger.outputters = Log4r::Outputter.stderr
107
+ logger.level = level
108
+ logger = nil
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,55 @@
1
+ module VagrantPlugins
2
+ module Unison
3
+ class ShellCommand
4
+ def initialize machine, paths, ssh_command
5
+ @machine = machine
6
+ @paths = paths
7
+ @ssh_command = ssh_command
8
+ end
9
+
10
+ attr_accessor :batch, :repeat, :terse
11
+
12
+ def to_a
13
+ args.map do |arg|
14
+ arg = arg[1...-1] if arg =~ /\A"(.*)"\z/
15
+ arg
16
+ end
17
+ end
18
+
19
+ def to_s
20
+ args.join(' ')
21
+ end
22
+
23
+ private
24
+
25
+ def args
26
+ [
27
+ 'unison',
28
+ @paths.host,
29
+ @ssh_command.uri,
30
+ batch_arg,
31
+ terse_arg,
32
+ repeat_arg,
33
+ ignore_arg,
34
+ ['-sshargs', %("#{@ssh_command.command}")],
35
+ ].flatten.compact
36
+ end
37
+
38
+ def batch_arg
39
+ '-batch' if batch
40
+ end
41
+
42
+ def ignore_arg
43
+ ['-ignore', %("#{@machine.config.unison.ignore}")] if @machine.config.unison.ignore
44
+ end
45
+
46
+ def repeat_arg
47
+ ['-repeat', @machine.config.unison.repeat] if repeat && @machine.config.unison.repeat
48
+ end
49
+
50
+ def terse_arg
51
+ '-terse' if terse
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,43 @@
1
+ module VagrantPlugins
2
+ module Unison
3
+ class SshCommand
4
+ def initialize(machine, unison_paths)
5
+ @machine = machine
6
+ @unison_paths = unison_paths
7
+ end
8
+
9
+ def command
10
+ %W(
11
+ -p #{ssh_info[:port]}
12
+ #{proxy_command}
13
+ -o StrictHostKeyChecking=no
14
+ -o UserKnownHostsFile=/dev/null
15
+ #{key_paths}
16
+ ).compact.join(' ')
17
+ end
18
+
19
+ def uri
20
+ username = ssh_info[:username]
21
+ host = ssh_info[:host]
22
+
23
+ "ssh://#{username}@#{host}/#{@unison_paths.guest}"
24
+ end
25
+
26
+ private
27
+
28
+ def proxy_command
29
+ command = ssh_info[:proxy_command]
30
+ return nil unless command
31
+ "-o ProxyCommand='#{command}'"
32
+ end
33
+
34
+ def ssh_info
35
+ @machine.ssh_info
36
+ end
37
+
38
+ def key_paths
39
+ ssh_info[:private_key_path].map { |p| "-i #{p}" }.join(' ')
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,24 @@
1
+ module VagrantPlugins
2
+ module Unison
3
+ class UnisonPaths
4
+ def initialize(env, machine)
5
+ @env = env
6
+ @machine = machine
7
+ end
8
+
9
+ def guest
10
+ @machine.config.unison.guest_folder
11
+ end
12
+
13
+ def host
14
+ @host ||= begin
15
+ path = File.expand_path(@machine.config.unison.host_folder, @env.root_path)
16
+
17
+ # Make sure there is a trailing slash on the host path to
18
+ # avoid creating an additional directory with rsync
19
+ path = "#{path}/" if path !~ /\/$/
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,22 @@
1
+ module VagrantPlugins
2
+ module Unison
3
+ module UnisonSync
4
+ def execute_sync_command(machine)
5
+ unison_paths = UnisonPaths.new(@env, machine)
6
+ guest_path = unison_paths.guest
7
+ host_path = unison_paths.host
8
+
9
+ @env.ui.info "Unisoning changes from {host}::#{host_path} --> {guest VM}::#{guest_path}"
10
+
11
+ # Create the guest path
12
+ machine.communicate.sudo("mkdir -p '#{guest_path}'")
13
+ machine.communicate.sudo("chown #{machine.ssh_info[:username]} '#{guest_path}'")
14
+
15
+ ssh_command = SshCommand.new(machine, unison_paths)
16
+ shell_command = ShellCommand.new(machine, unison_paths, ssh_command)
17
+
18
+ yield shell_command
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ module VagrantPlugins
2
+ module Unison
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ require "pathname"
2
+
3
+ require "vagrant-unison/plugin"
4
+ require "vagrant-unison/errors"
5
+
6
+ module VagrantPlugins
7
+ module Unison
8
+ # This returns the path to the source of this plugin.
9
+ #
10
+ # @return [Pathname]
11
+ def self.source_root
12
+ @source_root ||= Pathname.new(File.expand_path("../../", __FILE__))
13
+ end
14
+ end
15
+ end
data/locales/en.yml ADDED
@@ -0,0 +1,19 @@
1
+ en:
2
+ vagrant_unison:
3
+
4
+ config:
5
+ host_folder_required: |-
6
+ Host folder is required
7
+ guest_folder_required: |-
8
+ Guest folder is required
9
+
10
+ errors:
11
+ unison_error: |-
12
+ There was an error when attemping to sync folders using unison.
13
+ Please inspect the error message below for more info.
14
+
15
+ Host path: %{hostpath}
16
+ Guest path: %{guestpath}
17
+ Error: %{stderr}
18
+ Full command causing error:
19
+ %{command}
@@ -0,0 +1,32 @@
1
+ require "vagrant-unison/config"
2
+
3
+ describe VagrantPlugins::Unison::Config do
4
+ let(:instance) { described_class.new }
5
+
6
+ describe "defaults" do
7
+ subject do
8
+ instance.tap do |o|
9
+ o.finalize!
10
+ end
11
+ end
12
+
13
+ its("host_folder") { should be_nil }
14
+ its("guest_folder") { should be_nil }
15
+ its("ignore") { should be_nil }
16
+ end
17
+
18
+ describe "overriding defaults" do
19
+ # I typically don't meta-program in tests, but this is a very
20
+ # simple boilerplate test, so I cut corners here. It just sets
21
+ # each of these attributes to "foo" in isolation, and reads the value
22
+ # and asserts the proper result comes back out.
23
+ [:host_folder, :guest_folder].each do |attribute|
24
+
25
+ it "should not default #{attribute} if overridden" do
26
+ instance.send("#{attribute}=".to_sym, "foo")
27
+ instance.finalize!
28
+ instance.send(attribute).should == "foo"
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,58 @@
1
+ $:.unshift File.expand_path("../lib", __FILE__)
2
+ require "vagrant-unison/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "vagrant-unison2"
6
+ s.version = VagrantPlugins::Unison::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ["David Laing", "dmatora", "Danny Cosson"]
9
+ s.email = "dcosson@gmail.com"
10
+ s.homepage = "http://github.com/dcosson/vagrant-unison"
11
+ s.summary = "Vagrant 1.7+ plugin to sync local files to VM over SSH using Unison"
12
+ s.description = "Vagrant 1.7+ plugin to sync local files to VM over SSH using Unison"
13
+
14
+ s.required_rubygems_version = ">= 1.3.6"
15
+
16
+ s.add_runtime_dependency "listen", ">= 2.8.0"
17
+ s.add_runtime_dependency "rb-fsevent", "~> 0.9"
18
+
19
+ s.add_development_dependency "rake"
20
+ s.add_development_dependency "rspec-core", "~> 2.12.2"
21
+ s.add_development_dependency "rspec-expectations", "~> 2.12.1"
22
+ s.add_development_dependency "rspec-mocks", "~> 2.12.1"
23
+
24
+ # The following block of code determines the files that should be included
25
+ # in the gem. It does this by reading all the files in the directory where
26
+ # this gemspec is, and parsing out the ignored files from the gitignore.
27
+ # Note that the entire gitignore(5) syntax is not supported, specifically
28
+ # the "!" syntax, but it should mostly work correctly.
29
+ root_path = File.dirname(__FILE__)
30
+ all_files = Dir.chdir(root_path) { Dir.glob("**/{*,.*}") }
31
+ all_files.reject! { |file| [".", ".."].include?(File.basename(file)) }
32
+ gitignore_path = File.join(root_path, ".gitignore")
33
+ gitignore = File.readlines(gitignore_path)
34
+ gitignore.map! { |line| line.chomp.strip }
35
+ gitignore.reject! { |line| line.empty? || line =~ /^(#|!)/ }
36
+
37
+ unignored_files = all_files.reject do |file|
38
+ # Ignore any directories, the gemspec only cares about files
39
+ next true if File.directory?(file)
40
+
41
+ # Ignore any paths that match anything in the gitignore. We do
42
+ # two tests here:
43
+ #
44
+ # - First, test to see if the entire path matches the gitignore.
45
+ # - Second, match if the basename does, this makes it so that things
46
+ # like '.DS_Store' will match sub-directories too (same behavior
47
+ # as git).
48
+ #
49
+ gitignore.any? do |ignore|
50
+ File.fnmatch(ignore, file, File::FNM_PATHNAME) ||
51
+ File.fnmatch(ignore, File.basename(file), File::FNM_PATHNAME)
52
+ end
53
+ end
54
+
55
+ s.files = unignored_files
56
+ s.executables = unignored_files.map { |f| f[/^bin\/(.*)/, 1] }.compact
57
+ s.require_path = 'lib'
58
+ end
metadata ADDED
@@ -0,0 +1,147 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vagrant-unison2
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - David Laing
8
+ - dmatora
9
+ - Danny Cosson
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2016-01-23 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: listen
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: 2.8.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: 2.8.0
29
+ - !ruby/object:Gem::Dependency
30
+ name: rb-fsevent
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: '0.9'
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '0.9'
43
+ - !ruby/object:Gem::Dependency
44
+ name: rake
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ - !ruby/object:Gem::Dependency
58
+ name: rspec-core
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - "~>"
62
+ - !ruby/object:Gem::Version
63
+ version: 2.12.2
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - "~>"
69
+ - !ruby/object:Gem::Version
70
+ version: 2.12.2
71
+ - !ruby/object:Gem::Dependency
72
+ name: rspec-expectations
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - "~>"
76
+ - !ruby/object:Gem::Version
77
+ version: 2.12.1
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - "~>"
83
+ - !ruby/object:Gem::Version
84
+ version: 2.12.1
85
+ - !ruby/object:Gem::Dependency
86
+ name: rspec-mocks
87
+ requirement: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - "~>"
90
+ - !ruby/object:Gem::Version
91
+ version: 2.12.1
92
+ type: :development
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - "~>"
97
+ - !ruby/object:Gem::Version
98
+ version: 2.12.1
99
+ description: Vagrant 1.7+ plugin to sync local files to VM over SSH using Unison
100
+ email: dcosson@gmail.com
101
+ executables: []
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - ".gitignore"
106
+ - CHANGELOG.md
107
+ - Gemfile
108
+ - LICENSE
109
+ - README.md
110
+ - Rakefile
111
+ - lib/vagrant-unison.rb
112
+ - lib/vagrant-unison/command.rb
113
+ - lib/vagrant-unison/config.rb
114
+ - lib/vagrant-unison/errors.rb
115
+ - lib/vagrant-unison/plugin.rb
116
+ - lib/vagrant-unison/shell_command.rb
117
+ - lib/vagrant-unison/ssh_command.rb
118
+ - lib/vagrant-unison/unison_paths.rb
119
+ - lib/vagrant-unison/unison_sync.rb
120
+ - lib/vagrant-unison/version.rb
121
+ - locales/en.yml
122
+ - spec/vagrant-unison/config_spec.rb
123
+ - vagrant-unison2.gemspec
124
+ homepage: http://github.com/dcosson/vagrant-unison
125
+ licenses: []
126
+ metadata: {}
127
+ post_install_message:
128
+ rdoc_options: []
129
+ require_paths:
130
+ - lib
131
+ required_ruby_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: 1.3.6
141
+ requirements: []
142
+ rubyforge_project:
143
+ rubygems_version: 2.4.5
144
+ signing_key:
145
+ specification_version: 4
146
+ summary: Vagrant 1.7+ plugin to sync local files to VM over SSH using Unison
147
+ test_files: []