vagrant-unison 0.0.1.dev

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,14 @@
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
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ # 0.1.0 (March, 2013)
2
+
3
+ * 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,65 @@
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`
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.vm.provider :sync do |sync|
28
+ sync.local_folder = "src/" #relative to the folder your Vagrantfile is in
29
+ sync.remote_folder = "src/" #relative to the vagrant home folder -> /home/vagrant
30
+ end
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 sync` to start watching the local_folder for changes, and syncing these to your vagrang VM.
38
+
39
+ Under the covers this uses your system installation of [Unison](http://www.cis.upenn.edu/~bcpierce/unison/),
40
+ which must be installed in your path.
41
+
42
+ ## Development
43
+
44
+ To work on the `vagrant-unison` plugin, clone this repository out, and use
45
+ [Bundler](http://gembundler.com) to get the dependencies:
46
+
47
+ ```
48
+ $ bundle
49
+ ```
50
+
51
+ Once you have the dependencies, verify the unit tests pass with `rake`:
52
+
53
+ ```
54
+ $ bundle exec rake
55
+ ```
56
+
57
+ If those pass, you're ready to start developing the plugin. You can test
58
+ the plugin without installing it into your Vagrant environment by just
59
+ creating a `Vagrantfile` in the top level of this directory (it is gitignored)
60
+ that uses it, and uses bundler to execute Vagrant:
61
+
62
+ ```
63
+ $ bundle exec vagrant up
64
+ $ bundle exec vagrant sync
65
+ ```
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,51 @@
1
+ require "log4r"
2
+ require "vagrant"
3
+
4
+ module VagrantPlugins
5
+ module Unison
6
+ class Command < Vagrant.plugin("2", :command)
7
+ def execute
8
+
9
+ with_target_vms do |machine|
10
+
11
+ ssh_info = machine.ssh_info
12
+
13
+ hostpath = File.expand_path(machine.config.sync.host_folder, @env.root_path)
14
+ guestpath = machine.config.sync.guest_folder
15
+
16
+ # Make sure there is a trailing slash on the host path to
17
+ # avoid creating an additional directory with rsync
18
+ hostpath = "#{hostpath}/" if hostpath !~ /\/$/
19
+
20
+ @env.ui.info "Unisoning {host}::#{hostpath} --> {guest VM}::#{guestpath}"
21
+
22
+ # Create the guest path
23
+ #machine.communicate.sudo("mkdir -p '#{guestpath}'")
24
+ #machine.communicate.sudo("chown #{ssh_info[:username]} '#{guestpath}'")
25
+
26
+ # Unison over to the guest path using the SSH info
27
+ command = [
28
+ "unison", "-batch",
29
+ "-ignore='Name {git*,.vagrant/,*.DS_Store}'",
30
+ "-sshargs=\"-p #{ssh_info[:port]} -o StrictHostKeyChecking=no -i '#{ssh_info[:private_key_path]}'\"",
31
+ hostpath,
32
+ "ssh://#{ssh_info[:username]}@#{ssh_info[:host]}/#{guestpath}"
33
+ ]
34
+
35
+ r = Vagrant::Util::Subprocess.execute(*command)
36
+ if r.exit_code != 0
37
+ raise Vagrant::Errors::UnisonError,
38
+ :command => command.join(" "),
39
+ :guestpath => guestpath,
40
+ :hostpath => hostpath,
41
+ :stderr => r.stderr
42
+ end
43
+
44
+ end
45
+
46
+ 0
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,52 @@
1
+ require "vagrant"
2
+
3
+ module VagrantPlugins
4
+ module Unison
5
+ class Config < Vagrant.plugin("2", :config)
6
+ # The access key ID for accessing AWS.
7
+ #
8
+ # @return [String]
9
+ attr_accessor :host_folder
10
+
11
+ # The ID of the AMI to use.
12
+ #
13
+ # @return [String]
14
+ attr_accessor :guest_folder
15
+
16
+ def initialize(region_specific=false)
17
+ @host_folder = UNSET_VALUE
18
+ @remote_folder = UNSET_VALUE
19
+ end
20
+
21
+ #-------------------------------------------------------------------
22
+ # Internal methods.
23
+ #-------------------------------------------------------------------
24
+
25
+ # def merge(other)
26
+ # super.tap do |result|
27
+ # # TODO - do something sensible; current last config wins
28
+ # result.local_folder = other.local_folder
29
+ # result.remote_folder = other.remote_folder
30
+ # end
31
+ # end
32
+
33
+ def finalize!
34
+ # The access keys default to nil
35
+ @host_folder = nil if @host_folder == UNSET_VALUE
36
+ @guest_folder = nil if @guest_folder == UNSET_VALUE
37
+
38
+ # Mark that we finalized
39
+ @__finalized = true
40
+ end
41
+
42
+ def validate(machine)
43
+ errors = []
44
+
45
+ errors << I18n.t("vagrant_sync.config.host_folder_required") if @host_folder.nil?
46
+ errors << I18n.t("vagrant_sync.config.guest_folder_required") if @guest_folder.nil?
47
+
48
+ { "Unison" => errors }
49
+ end
50
+ end
51
+ end
52
+ 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,73 @@
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 "sync" do
23
+ require_relative "config"
24
+ Config
25
+ end
26
+
27
+ command "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
+ # This initializes the internationalization strings.
38
+ def self.setup_i18n
39
+ I18n.load_path << File.expand_path("locales/en.yml", Unison.source_root)
40
+ I18n.reload!
41
+ end
42
+
43
+ # This sets up our log level to be whatever VAGRANT_LOG is.
44
+ def self.setup_logging
45
+ require "log4r"
46
+
47
+ level = nil
48
+ begin
49
+ level = Log4r.const_get(ENV["VAGRANT_LOG"].upcase)
50
+ rescue NameError
51
+ # This means that the logging constant wasn't found,
52
+ # which is fine. We just keep `level` as `nil`. But
53
+ # we tell the user.
54
+ level = nil
55
+ end
56
+
57
+ # Some constants, such as "true" resolve to booleans, so the
58
+ # above error checking doesn't catch it. This will check to make
59
+ # sure that the log level is an integer, as Log4r requires.
60
+ level = nil if !level.is_a?(Integer)
61
+
62
+ # Set the logging level on all "vagrant" namespaced
63
+ # logs as long as we have a valid level.
64
+ if level
65
+ logger = Log4r::Logger.new("vagrant_sync")
66
+ logger.outputters = Log4r::Outputter.stderr
67
+ logger.level = level
68
+ logger = nil
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,5 @@
1
+ module VagrantPlugins
2
+ module Unison
3
+ VERSION = "0.0.1.dev"
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,31 @@
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
+ end
16
+
17
+ describe "overriding defaults" do
18
+ # I typically don't meta-program in tests, but this is a very
19
+ # simple boilerplate test, so I cut corners here. It just sets
20
+ # each of these attributes to "foo" in isolation, and reads the value
21
+ # and asserts the proper result comes back out.
22
+ [:host_folder, :guest_folder].each do |attribute|
23
+
24
+ it "should not default #{attribute} if overridden" do
25
+ instance.send("#{attribute}=".to_sym, "foo")
26
+ instance.finalize!
27
+ instance.send(attribute).should == "foo"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,57 @@
1
+ $:.unshift File.expand_path("../lib", __FILE__)
2
+ require "vagrant-unison/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "vagrant-unison"
6
+ s.version = VagrantPlugins::Unison::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = "David Laing"
9
+ s.email = "david@davidlaing.com"
10
+ s.homepage = "http://github.com/mrdavidlaing/vagrant-unison"
11
+ s.summary = "Vagrant 1.1 plugin to sync local files to VM over SSH"
12
+ s.description = "Vagrant 1.1 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 "guard", "~> 1.6.2"
17
+
18
+ s.add_development_dependency "rake"
19
+ s.add_development_dependency "rspec-core", "~> 2.12.2"
20
+ s.add_development_dependency "rspec-expectations", "~> 2.12.1"
21
+ s.add_development_dependency "rspec-mocks", "~> 2.12.1"
22
+
23
+ # The following block of code determines the files that should be included
24
+ # in the gem. It does this by reading all the files in the directory where
25
+ # this gemspec is, and parsing out the ignored files from the gitignore.
26
+ # Note that the entire gitignore(5) syntax is not supported, specifically
27
+ # the "!" syntax, but it should mostly work correctly.
28
+ root_path = File.dirname(__FILE__)
29
+ all_files = Dir.chdir(root_path) { Dir.glob("**/{*,.*}") }
30
+ all_files.reject! { |file| [".", ".."].include?(File.basename(file)) }
31
+ gitignore_path = File.join(root_path, ".gitignore")
32
+ gitignore = File.readlines(gitignore_path)
33
+ gitignore.map! { |line| line.chomp.strip }
34
+ gitignore.reject! { |line| line.empty? || line =~ /^(#|!)/ }
35
+
36
+ unignored_files = all_files.reject do |file|
37
+ # Ignore any directories, the gemspec only cares about files
38
+ next true if File.directory?(file)
39
+
40
+ # Ignore any paths that match anything in the gitignore. We do
41
+ # two tests here:
42
+ #
43
+ # - First, test to see if the entire path matches the gitignore.
44
+ # - Second, match if the basename does, this makes it so that things
45
+ # like '.DS_Store' will match sub-directories too (same behavior
46
+ # as git).
47
+ #
48
+ gitignore.any? do |ignore|
49
+ File.fnmatch(ignore, file, File::FNM_PATHNAME) ||
50
+ File.fnmatch(ignore, File.basename(file), File::FNM_PATHNAME)
51
+ end
52
+ end
53
+
54
+ s.files = unignored_files
55
+ s.executables = unignored_files.map { |f| f[/^bin\/(.*)/, 1] }.compact
56
+ s.require_path = 'lib'
57
+ end
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vagrant-unison
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.dev
5
+ prerelease: 6
6
+ platform: ruby
7
+ authors:
8
+ - David Laing
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: guard
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.6.2
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 1.6.2
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec-core
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 2.12.2
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 2.12.2
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec-expectations
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 2.12.1
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 2.12.1
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec-mocks
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 2.12.1
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 2.12.1
94
+ description: Vagrant 1.1 plugin to sync local files to VM over SSH using Unison
95
+ email: david@davidlaing.com
96
+ executables: []
97
+ extensions: []
98
+ extra_rdoc_files: []
99
+ files:
100
+ - CHANGELOG.md
101
+ - Gemfile
102
+ - lib/vagrant-unison/command.rb
103
+ - lib/vagrant-unison/config.rb
104
+ - lib/vagrant-unison/errors.rb
105
+ - lib/vagrant-unison/plugin.rb
106
+ - lib/vagrant-unison/version.rb
107
+ - lib/vagrant-unison.rb
108
+ - LICENSE
109
+ - locales/en.yml
110
+ - Rakefile
111
+ - README.md
112
+ - spec/vagrant-unison/config_spec.rb
113
+ - vagrant-unison.gemspec
114
+ - .gitignore
115
+ homepage: http://github.com/mrdavidlaing/vagrant-unison
116
+ licenses: []
117
+ post_install_message:
118
+ rdoc_options: []
119
+ require_paths:
120
+ - lib
121
+ required_ruby_version: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ segments:
128
+ - 0
129
+ hash: -244591167083494595
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ! '>='
134
+ - !ruby/object:Gem::Version
135
+ version: 1.3.6
136
+ requirements: []
137
+ rubyforge_project:
138
+ rubygems_version: 1.8.24
139
+ signing_key:
140
+ specification_version: 3
141
+ summary: Vagrant 1.1 plugin to sync local files to VM over SSH
142
+ test_files: []