vagrant-bindfs 0.4.14 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +66 -4
  3. data/Rakefile +11 -7
  4. data/Vagrantfile +10 -8
  5. data/lib/vagrant-bindfs.rb +10 -16
  6. data/lib/vagrant-bindfs/bindfs.rb +15 -0
  7. data/lib/vagrant-bindfs/bindfs/command.rb +47 -0
  8. data/lib/vagrant-bindfs/bindfs/folder.rb +38 -0
  9. data/lib/vagrant-bindfs/bindfs/option_definitions.json +67 -0
  10. data/lib/vagrant-bindfs/bindfs/option_set.rb +105 -0
  11. data/lib/vagrant-bindfs/bindfs/validators.rb +9 -0
  12. data/lib/vagrant-bindfs/bindfs/validators/config.rb +58 -0
  13. data/lib/vagrant-bindfs/bindfs/validators/runtime.rb +56 -0
  14. data/lib/vagrant-bindfs/vagrant.rb +12 -0
  15. data/lib/vagrant-bindfs/vagrant/actions.rb +11 -0
  16. data/lib/vagrant-bindfs/vagrant/actions/concerns.rb +11 -0
  17. data/lib/vagrant-bindfs/vagrant/actions/concerns/log.rb +34 -0
  18. data/lib/vagrant-bindfs/vagrant/actions/concerns/machine.rb +31 -0
  19. data/lib/vagrant-bindfs/vagrant/actions/installer.rb +99 -0
  20. data/lib/vagrant-bindfs/vagrant/actions/mounter.rb +65 -0
  21. data/lib/vagrant-bindfs/vagrant/capabilities.rb +108 -0
  22. data/lib/vagrant-bindfs/vagrant/capabilities/all.rb +12 -0
  23. data/lib/vagrant-bindfs/vagrant/capabilities/all/bindfs.rb +53 -0
  24. data/lib/vagrant-bindfs/vagrant/capabilities/all/package_manager.rb +17 -0
  25. data/lib/vagrant-bindfs/vagrant/capabilities/all/system_checks.rb +20 -0
  26. data/lib/vagrant-bindfs/vagrant/capabilities/darwin.rb +13 -0
  27. data/lib/vagrant-bindfs/vagrant/capabilities/darwin/bindfs.rb +33 -0
  28. data/lib/vagrant-bindfs/vagrant/capabilities/darwin/fuse.rb +32 -0
  29. data/lib/vagrant-bindfs/vagrant/capabilities/darwin/package_manager.rb +24 -0
  30. data/lib/vagrant-bindfs/{cap/darwin/checks.rb → vagrant/capabilities/darwin/system_checks.rb} +7 -8
  31. data/lib/vagrant-bindfs/vagrant/capabilities/debian.rb +12 -0
  32. data/lib/vagrant-bindfs/vagrant/capabilities/debian/bindfs.rb +39 -0
  33. data/lib/vagrant-bindfs/vagrant/capabilities/debian/fuse.rb +16 -0
  34. data/lib/vagrant-bindfs/vagrant/capabilities/debian/package_manager.rb +20 -0
  35. data/lib/vagrant-bindfs/vagrant/capabilities/linux.rb +12 -0
  36. data/lib/vagrant-bindfs/vagrant/capabilities/linux/fuse.rb +24 -0
  37. data/lib/vagrant-bindfs/vagrant/capabilities/linux/package_manager.rb +16 -0
  38. data/lib/vagrant-bindfs/vagrant/capabilities/linux/system_checks.rb +26 -0
  39. data/lib/vagrant-bindfs/vagrant/capabilities/redhat.rb +12 -0
  40. data/lib/vagrant-bindfs/vagrant/capabilities/redhat/bindfs.rb +39 -0
  41. data/lib/vagrant-bindfs/vagrant/capabilities/redhat/fuse.rb +17 -0
  42. data/lib/vagrant-bindfs/vagrant/capabilities/redhat/package_manager.rb +20 -0
  43. data/lib/vagrant-bindfs/vagrant/capabilities/suse.rb +12 -0
  44. data/lib/vagrant-bindfs/vagrant/capabilities/suse/bindfs.rb +41 -0
  45. data/lib/vagrant-bindfs/vagrant/capabilities/suse/fuse.rb +17 -0
  46. data/lib/vagrant-bindfs/vagrant/capabilities/suse/package_manager.rb +20 -0
  47. data/lib/vagrant-bindfs/vagrant/capabilities/ubuntu.rb +10 -0
  48. data/lib/vagrant-bindfs/vagrant/capabilities/ubuntu/fuse.rb +23 -0
  49. data/lib/vagrant-bindfs/vagrant/config.rb +86 -0
  50. data/lib/vagrant-bindfs/vagrant/errors.rb +12 -0
  51. data/lib/vagrant-bindfs/vagrant/plugin.rb +43 -0
  52. data/lib/vagrant-bindfs/version.rb +3 -12
  53. data/locales/en.yml +71 -26
  54. metadata +48 -23
  55. data/lib/vagrant-bindfs/bind.rb +0 -109
  56. data/lib/vagrant-bindfs/cap/all/bindfs_installed.rb +0 -17
  57. data/lib/vagrant-bindfs/cap/all/checks.rb +0 -17
  58. data/lib/vagrant-bindfs/cap/darwin/fuse_loaded.rb +0 -19
  59. data/lib/vagrant-bindfs/cap/darwin/install_bindfs.rb +0 -61
  60. data/lib/vagrant-bindfs/cap/debian/install_bindfs.rb +0 -17
  61. data/lib/vagrant-bindfs/cap/fedora/install_bindfs.rb +0 -17
  62. data/lib/vagrant-bindfs/cap/linux/bindfs_installed.rb +0 -17
  63. data/lib/vagrant-bindfs/cap/linux/checks.rb +0 -21
  64. data/lib/vagrant-bindfs/cap/linux/enable_fuse.rb +0 -17
  65. data/lib/vagrant-bindfs/cap/linux/fuse_loaded.rb +0 -17
  66. data/lib/vagrant-bindfs/cap/redhat/install_bindfs.rb +0 -52
  67. data/lib/vagrant-bindfs/cap/suse/install_bindfs.rb +0 -17
  68. data/lib/vagrant-bindfs/cap/ubuntu/fuse_loaded.rb +0 -19
  69. data/lib/vagrant-bindfs/command.rb +0 -212
  70. data/lib/vagrant-bindfs/config.rb +0 -119
  71. data/lib/vagrant-bindfs/errors.rb +0 -7
  72. data/lib/vagrant-bindfs/plugin.rb +0 -145
  73. data/test/test_helper.rb +0 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 13ab236d53312e92a8d851fa46964c9058fa9a8b
4
- data.tar.gz: aa0e37cc87f7e0e707586b38c1cb78d2c90ebccb
3
+ metadata.gz: 3903f446b7220c7e235c01977a3789744ae0f0ac
4
+ data.tar.gz: de5fc9b8abfed184d121b2c7fc498cd7de4aa41d
5
5
  SHA512:
6
- metadata.gz: 2a2b1bdd830b77ec846268f3e9590994e119f93f86861f0d9a27835fe96c277d0857d89bed78fea3bac0befe6640f186f32ae11b7a246751849688b9013fd5fc
7
- data.tar.gz: 58e53b1e04a653827eeef66448772346e51098c64ef37a90bcbad6a3b588f59aba4c5c1c1900155f806ccb7da792513faf0ab39c8a9ff10d4ee278e228eb799c
6
+ metadata.gz: 4a15651cbd0dae8d3047973e20ca341f3511e84a1e713e3ca5e68d02fb6a19b576e0916b6b75db0c3be32288c1ce2dd708e1b5847c1a7924257fe8be504b3c2e
7
+ data.tar.gz: 360223491717333c79ea2060d52fb3b5e6cb20a57a5dac7b443feda2f1b9c4d5d892ee34e5cb6a1c196c400721cd25ac8c6c2adf0ff442396a047a98c0e3abd6
data/README.md CHANGED
@@ -42,7 +42,7 @@ config.bindfs.bind_folder "/path/to/source", "/path/to/destination", options
42
42
  ```
43
43
 
44
44
  By default, all folders are binded after folders syncing between host and guest machines.
45
- You can pass a special `:after` (or `:hook`) option to the bind_folder method to choose when a folder should be binded.
45
+ You can pass a special `:after` option to the bind_folder method to choose when a folder should be binded.
46
46
  Supported values are :
47
47
 
48
48
  * `:synced_folders` (default)
@@ -95,8 +95,6 @@ Both long arguments and shorthand are supported.
95
95
  If you set both, shorthand will prevail.
96
96
  Long arguments can be written indifferently with underscore ('force_user') or dash ('force-user') and as strings (:'force-user') or symbols (:force_user).
97
97
 
98
- You can overwrite default options _via_ `config.bindfs.default_options`.
99
-
100
98
  vagrant-bindfs detects installed version of bindfs, translate option names when needed and ignore an option if it is not supported.
101
99
  As we may have missed something, it will warn you when a binding command fail.
102
100
 
@@ -105,12 +103,76 @@ On other system, you'll get warned.
105
103
 
106
104
  OS X guests may need some specific options. See [bindfs README](https://github.com/mpartel/bindfs#os-x-note) for details.
107
105
 
106
+ ## Configuration
107
+
108
+ This plugin supports the following configuration options
109
+
110
+ ### `debug`
111
+
112
+ Setting `config.bindfs.debug` to true will increase the verbosity level of this plugin in Vagrant output.
113
+
114
+ ### `default_options`
115
+
116
+ You can overwrite default bindfs options _via_ `config.bindfs.default_options=`.
117
+
118
+ ```ruby
119
+ Vagrant.configure("2") do |config|
120
+
121
+ # These values are the default options
122
+ config.bindfs.default_options = {
123
+ force_user: 'vagrant',
124
+ force_group: 'vagrant',
125
+ perms: 'u=rwX:g=rD:o=rD'
126
+ }
127
+
128
+ end
129
+ ```
130
+
131
+ ### `skip_validations`
132
+
133
+ By default, `vagrant-bindfs` will check if the user and the group set for a binded folder exist on the virtual machine.
134
+ If either one, the other or both of them are missing, it will warn you and not execute any bindfs command for this folder.
135
+
136
+ To skip these validations, you can add `:user`and/or `:group` to the `config.bindfs.skip_validations` array.
137
+
138
+
139
+ ```ruby
140
+ Vagrant.configure("2") do |config|
141
+
142
+ config.bindfs.skip_validations << :user
143
+
144
+ end
145
+ ```
146
+
147
+ ### `bindfs_version` and `install_bindfs_from_source`
148
+
149
+ By default, if `bindfs` needs to be installed on the virtual machine, `vagrant-bindfs` will install the most recent release available in repositories (_via_ `homebrew` for OS X guests).
150
+ If no version of `bindfs` is found, it will try to install the most recent supported version of `bindfs` from source. (See [lib/vagrant-bindfs/bindfs.rb](https://github.com/gael-ian/vagrant-bindfs/blob/master/lib/vagrant-bindfs/bindfs.rb#L4) for the exact version number).
151
+
152
+ You can force the plugin to install the version of `bindfs` of your choice with the `bindfs_version` configuration option.
153
+ It will then look for the specified version in repositories and install it if available. If not, it will install it from sources.
154
+
155
+ You can also force installation from sources with the `install_bindfs_from_source` configuration option.
156
+ This will skip any repositories look up.
157
+
158
+ ```ruby
159
+ Vagrant.configure("2") do |config|
160
+
161
+ # This will force the plugin to install bindfs-1.12.2 from sources
162
+ config.bindfs.bindfs_version = "1.12.2"
163
+ config.bindfs.install_bindfs_from_source = true
164
+
165
+ end
166
+ ```
167
+
168
+ **This feature only works with exact version match and does not try to resolve dependencies.**
169
+ In particular, Fuse will always be installed from the latest version available in repositories (_via_ Homebrew Cask for OS X guests).
108
170
 
109
171
  ## Contributing
110
172
 
111
173
  If you find this plugin useful, we could use a few enhancements!
112
174
  In particular, capabilities files for installing vagrant-bindfs on other systems would be useful.
113
- We could also use some specs…
175
+ We could also use some more specs…
114
176
 
115
177
 
116
178
  ### How to Test Changes
data/Rakefile CHANGED
@@ -1,20 +1,24 @@
1
- require "rubygems"
2
- require "bundler/setup"
3
-
4
- #require "rspec/core/rake_task"
1
+ # frozen_string_literal: true
2
+ require 'rubygems'
3
+ require 'bundler/setup'
4
+ require 'rspec/core/rake_task'
5
+ require 'rubocop/rake_task'
5
6
 
6
7
  # Immediately sync all stdout
7
8
  $stdout.sync = true
8
9
  $stderr.sync = true
9
10
 
10
11
  # Change to the directory of this file
11
- Dir.chdir(File.expand_path("../", __FILE__))
12
+ Dir.chdir(File.expand_path('../', __FILE__))
12
13
 
13
14
  # Installs the tasks for gem creation
14
15
  Bundler::GemHelper.install_tasks
15
16
 
16
17
  # Install the `spec` task so that we can run tests
17
- #RSpec::Core::RakeTask.new
18
+ RSpec::Core::RakeTask.new
19
+
20
+ # Add Rubocop tasks
21
+ RuboCop::RakeTask.new
18
22
 
19
23
  # Default task is to run the unit tests
20
- #task :default => "spec"
24
+ task default: 'spec'
data/Vagrantfile CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # -*- mode: ruby -*-
2
3
  # vi: set ft=ruby :
3
4
 
@@ -7,10 +8,10 @@ test_machines = {
7
8
  # ubuntu: { box: "bento/ubuntu-16.04" },
8
9
  # fedora: { box: "bento/fedora-24" },
9
10
  # redhat: { box: "bento/centos-7.2" },
10
-
11
+
11
12
  # The `vagrant` user group does not exist in this box.
12
13
  # suse: { box: "bento/opensuse-leap-42.1", args: { group: 'users' } },
13
-
14
+
14
15
  # **This box require the Oracle VM VirtualBox Extension Pack for Virtualbox.**
15
16
  # The `vagrant` user group does not exist in this box.
16
17
  # osx: { box: "jhcook/osx-elcapitan-10.11", args: { group: 'staff' } },
@@ -21,16 +22,18 @@ test_machines = {
21
22
  # documentation. See https://goo.gl/LbkPVF
22
23
  }
23
24
 
24
- require File.expand_path("../test/test_helper", __FILE__)
25
-
26
- Vagrant.configure("2") do |config|
25
+ require File.expand_path('../spec/vagrantfile_helper', __FILE__)
27
26
 
27
+ Vagrant.configure('2') do |config|
28
28
  # Common configuration
29
- config.vm.provider "virtualbox" do |vb|
30
- vb.memory = 512
29
+ config.vm.provider 'virtualbox' do |vb|
30
+ vb.memory = 4096
31
31
  vb.cpus = 2
32
32
  end
33
33
 
34
+ # For a more detailled output when you test, set this to true.
35
+ config.bindfs.debug = false
36
+
34
37
  test_machines.each do |distro, options|
35
38
  config.vm.define "vagrant-bindfs-test-#{distro}" do |machine|
36
39
  machine.vm.box = options[:box]
@@ -38,4 +41,3 @@ Vagrant.configure("2") do |config|
38
41
  end
39
42
  end
40
43
  end
41
-
@@ -1,22 +1,16 @@
1
+ # frozen_string_literal: true
1
2
  begin
2
- require "vagrant"
3
+ require 'vagrant'
3
4
  rescue LoadError
4
- raise "The Vagrant bindfs plugin must be run within Vagrant"
5
+ raise 'The Vagrant bindfs plugin must be run within Vagrant'
5
6
  end
6
7
 
7
- require "vagrant-bindfs/plugin"
8
- require "vagrant-bindfs/errors"
9
-
10
- require "pathname"
8
+ module VagrantBindfs
9
+ autoload :Vagrant, 'vagrant-bindfs/vagrant'
10
+ autoload :Bindfs, 'vagrant-bindfs/bindfs'
11
+ end
11
12
 
12
- module VagrantPlugins
13
- module Bindfs
14
-
15
- def self.source_root
16
- @source_root ||= Pathname.new(File.expand_path("../../", __FILE__))
17
- end
13
+ I18n.load_path << File.expand_path('../../locales/en.yml', __FILE__)
14
+ I18n.reload!
18
15
 
19
- I18n.load_path << File.expand_path("locales/en.yml", source_root)
20
- I18n.reload!
21
- end
22
- end
16
+ require 'vagrant-bindfs/vagrant/plugin'
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+ module VagrantBindfs
3
+ module Bindfs
4
+ SOURCE_VERSION = '1.13.4'
5
+ SOURCE_URLS = [
6
+ 'http://bindfs.org/downloads/bindfs-%{bindfs_version}.tar.gz',
7
+ 'http://bindfs.dnsalias.net/downloads/bindfs-%{bindfs_version}.tar.gz'
8
+ ].freeze
9
+
10
+ autoload :Command, 'vagrant-bindfs/bindfs/command'
11
+ autoload :Folder, 'vagrant-bindfs/bindfs/folder'
12
+ autoload :OptionSet, 'vagrant-bindfs/bindfs/option_set'
13
+ autoload :Validators, 'vagrant-bindfs/bindfs/validators'
14
+ end
15
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+ module VagrantBindfs
3
+ module Bindfs
4
+ class Command
5
+ attr_reader :folder
6
+
7
+ def initialize(folder)
8
+ @folder = folder
9
+ end
10
+
11
+ def to_s
12
+ ['bindfs', arguments_for(folder.options).join(' '), folder.source, folder.destination].compact.join(' ')
13
+ end
14
+
15
+ protected
16
+
17
+ def arguments_for(options)
18
+ options.each_with_object([]) do |(name, value), args|
19
+ args << format_argument(name, value) unless value.nil?
20
+ args
21
+ end.compact
22
+ end
23
+
24
+ def format_argument(name, value)
25
+ definition = argument_definition(name)
26
+ compatible_name = argument_compatible_name(name)
27
+
28
+ if definition['type'] == 'flag' && !!value
29
+ return "-#{compatible_name}" if definition['long'].empty? # Shorthand only options
30
+ return "--#{compatible_name}"
31
+ end
32
+ if definition['type'] == 'option'
33
+ return "-#{compatible_name} #{value}" if definition['long'].empty? # Shorthand only options
34
+ return "--#{compatible_name}=#{value}"
35
+ end
36
+ end
37
+
38
+ def argument_definition(name)
39
+ Bindfs::OptionSet.bindfs_options[name]
40
+ end
41
+
42
+ def argument_compatible_name(name)
43
+ Bindfs::OptionSet.compatible_name_for_version(name, @folder.options.version)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+ require 'digest/sha1'
3
+
4
+ module VagrantBindfs
5
+ module Bindfs
6
+ class Folder
7
+ attr_reader :source
8
+ attr_reader :destination
9
+ attr_reader :options
10
+
11
+ attr_reader :hook
12
+
13
+ def initialize(hook, source, destination, options = {})
14
+ @hook = hook
15
+
16
+ @source = source
17
+ @destination = destination
18
+ @options = Bindfs::OptionSet.new(nil, options)
19
+ end
20
+
21
+ def id
22
+ @id ||= Digest::SHA1.new.digest(destination)
23
+ end
24
+
25
+ def reverse_merge!(options)
26
+ @options = Bindfs::OptionSet.new(nil, options).merge(@options)
27
+ end
28
+
29
+ def merge!(options)
30
+ @options = @options.merge(options)
31
+ end
32
+
33
+ def to_version!(version)
34
+ @options = @options.to_version(version)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,67 @@
1
+ // TODO: Update after each bindfs release
2
+ {
3
+ // "File" ownership
4
+ "force-user": { "long": ["force-user", "user", "owner"], "short": ["u"], "type": "option", "since": "0.0.1" },
5
+ "force-group": { "long": ["force-group", "group"], "short": ["g"], "type": "option", "since": "0.0.1" },
6
+ "perms": { "long": ["perms"], "short": ["p"], "type": "option", "since": "0.0.1" },
7
+ "mirror": { "long": ["mirror"], "short": ["m"], "type": "option", "since": "0.0.1" },
8
+ "mirror-only": { "long": ["mirror-only"], "short": ["M"], "type": "option", "since": "0.0.1" },
9
+ "map": { "long": ["map"], "short": [], "type": "option", "since": "1.10" },
10
+ "uid-offset": { "long": ["uid-offset"], "short": [], "type": "option", "since": "1.13.2" },
11
+ "gid-offset": { "long": ["gid-offset"], "short": [], "type": "option", "since": "1.13.2" },
12
+
13
+ // File creation policy
14
+ "create-as-user": { "long": ["create-as-user"], "short": [], "type": "flag", "since": "0.0.1" },
15
+ "create-as-mounter": { "long": ["create-as-mounter"], "short": [], "type": "flag", "since": "0.0.1" },
16
+ "create-for-user": { "long": ["create-for-user"], "short": [], "type": "option", "since": "0.0.1" },
17
+ "create-for-group": { "long": ["create-for-group"], "short": [], "type": "option", "since": "0.0.1" },
18
+ "create-with-perms": { "long": ["create-with-perms"], "short": [], "type": "option", "since": "0.0.1" },
19
+
20
+ // Chown policy
21
+ "chown-normal": { "long": ["chown-normal"], "short": [], "type": "flag", "since": "0.0.1" },
22
+ "chown-ignore": { "long": ["chown-ignore"], "short": [], "type": "flag", "since": "0.0.1" },
23
+ "chown-deny": { "long": ["chown-deny"], "short": [], "type": "flag", "since": "0.0.1" },
24
+
25
+ // Chgrp policy
26
+ "chgrp-normal": { "long": ["chgrp-normal"], "short": [], "type": "flag", "since": "0.0.1" },
27
+ "chgrp-ignore": { "long": ["chgrp-ignore"], "short": [], "type": "flag", "since": "0.0.1" },
28
+ "chgrp-deny": { "long": ["chgrp-deny"], "short": [], "type": "flag", "since": "0.0.1" },
29
+
30
+ // Chmod policy
31
+ "chmod-normal": { "long": ["chmod-normal"], "short": [], "type": "flag", "since": "0.0.1" },
32
+ "chmod-ignore": { "long": ["chmod-ignore"], "short": [], "type": "flag", "since": "0.0.1" },
33
+ "chmod-deny": { "long": ["chmod-deny"], "short": [], "type": "flag", "since": "0.0.1" },
34
+ "chmod-filter": { "long": ["chmod-filter"], "short": [], "type": "option", "since": "1.12.2" },
35
+ "chmod-allow-x": { "long": ["chmod-allow-x"], "short": [], "type": "flag", "since": "0.0.1" },
36
+
37
+ // Extended attribute policy
38
+ "xattr-none": { "long": ["xattr-none"], "short": [], "type": "flag", "since": "0.0.1" },
39
+ "xattr-ro": { "long": ["xattr-ro"], "short": [], "type": "flag", "since": "0.0.1" },
40
+ "xattr-rw": { "long": ["xattr-rw"], "short": [], "type": "flag", "since": "0.0.1" },
41
+
42
+ // Rate limits
43
+ "read-rate": { "long": ["read-rate"], "short": [], "type": "option", "since": "1.12.6" },
44
+ "write-rate": { "long": ["write-rate"], "short": [], "type": "option", "since": "1.12.6" },
45
+
46
+ // Link handling
47
+ "hide-hard-links": { "long": ["hide-hard-links"], "short": [], "type": "flag", "since": "1.10" },
48
+ "resolve-symlinks": { "long": ["resolve-symlinks"], "short": [], "type": "flag", "since": "1.13.0" },
49
+ "resolve-symlink-policy": { "long": ["resolve-symlink-policy"], "short": [], "type": "option", "since": "1.13.0" },
50
+
51
+ // Multithreading
52
+ "multithreaded": { "long": ["multithreaded"], "short": [], "type": "flag", "since": "1.11" },
53
+ "enable-lock-forwarding": { "long": ["enable-lock-forwarding"], "short": [], "type": "flag", "since": "1.13.2" },
54
+ "disable-lock-forwarding": { "long": ["disable-lock-forwarding"], "short": [], "type": "flag", "since": "1.13.2" },
55
+
56
+ // Miscellaneous
57
+ "no-allow-other": { "long": ["no-allow-other"], "short": ["n"], "type": "flag", "since": "0.0.1" },
58
+ "realistic-permissions": { "long": ["realistic-permissions"], "short": [], "type": "flag", "since": "1.10" },
59
+ "ctime-from-mtime": { "long": ["ctime-from-mtime"], "short": [], "type": "flag", "since": "0.0.1" },
60
+ "enabe-ioctl": { "long": ["enable-ioctl"], "short": [], "type": "flag", "since": "1.13.2" },
61
+
62
+ // FUSE options
63
+ "o": { "long": [], "short": ["o"], "type": "option", "since": "0.0.1" },
64
+ "r": { "long": [], "short": ["r"], "type": "flag", "since": "0.0.1" },
65
+ "d": { "long": [], "short": ["d"], "type": "flag", "since": "0.0.1" },
66
+ "f": { "long": [], "short": ["f"], "type": "flag", "since": "0.0.1" }
67
+ }
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+ module VagrantBindfs
3
+ module Bindfs
4
+ class OptionSet
5
+ attr_reader :version
6
+
7
+ attr_reader :options
8
+ attr_reader :invalid_options
9
+ attr_reader :unsupported_options
10
+
11
+ include Enumerable
12
+ extend Forwardable
13
+ [:each, :[], :keys, :key?].each do |method|
14
+ def_delegator :@options, method
15
+ end
16
+
17
+ def initialize(version = nil, options = {})
18
+ @version = version
19
+ @options = normalize_option_names(options)
20
+ @invalid_options = {}
21
+ @unsupported_options = {}
22
+
23
+ extract_invalid_options!
24
+ extract_unsupported_options!
25
+ end
26
+
27
+ def merge!(other)
28
+ other = other.to_version(version) if other.respond_to?(:to_version)
29
+ @options.merge!(normalize_option_names(other))
30
+ extract_invalid_options!
31
+ extract_unsupported_options!
32
+ end
33
+
34
+ def merge(other)
35
+ dup.tap { |result| result.merge!(other) }
36
+ end
37
+
38
+ def to_version(new_version)
39
+ self.class.new(new_version, @options.merge(invalid_options).merge(unsupported_options))
40
+ end
41
+
42
+ protected
43
+
44
+ def normalize_option_names(options)
45
+ options.each_with_object({}) do |(key, value), normalized|
46
+ normalized_key = key.to_s.tr('_', '-')
47
+ canonical_name = canonical_option_name(normalized_key)
48
+
49
+ if normalized.key?(canonical_name)
50
+ raise VagrantBindfs::Vagrant::ConfigError.new(:conflicting_options, name: canonical_name)
51
+ end
52
+
53
+ normalized[canonical_name] = value
54
+ normalized
55
+ end
56
+ end
57
+
58
+ def canonical_option_name(option_name)
59
+ self.class.bindfs_options.each do |name, definition|
60
+ return name if definition['short'].include?(option_name)
61
+ return name if definition['long'].include?(option_name)
62
+ end
63
+ option_name
64
+ end
65
+
66
+ def extract_invalid_options!
67
+ extract_options_by_names!(options.keys - self.class.bindfs_options.keys, @invalid_options)
68
+ end
69
+
70
+ def extract_unsupported_options!
71
+ extract_options_by_names!(options.keys - self.class.supported_options(version).keys, @unsupported_options)
72
+ end
73
+
74
+ def extract_options_by_names!(names, to)
75
+ return {} if names.empty?
76
+ names.each { |name| to[name] = @options.delete(name) }
77
+ end
78
+
79
+ class << self
80
+ def bindfs_options
81
+ @bindfs_options ||= JSON.parse(File.read(File.expand_path('../option_definitions.json', __FILE__)))
82
+ end
83
+
84
+ def supported_options(version)
85
+ bindfs_options.each_with_object({}) do |(name, definition), supported|
86
+ supported[name] = definition if version.nil? || !version_lower_than(version, definition['since'])
87
+ supported
88
+ end
89
+ end
90
+
91
+ def compatible_name_for_version(option_name, version)
92
+ return 'user' if option_name == 'force-user' && version_lower_than(version, '1.12')
93
+ return 'group' if option_name == 'force-group' && version_lower_than(version, '1.12')
94
+ option_name
95
+ end
96
+
97
+ protected
98
+
99
+ def version_lower_than(version, target)
100
+ Gem::Version.new(version) < Gem::Version.new(target)
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end