revenc 0.1.3 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemfiles +53 -0
- data/.gitignore +4 -8
- data/Gemfile.lock +42 -37
- data/HISTORY.markdown +9 -2
- data/LICENSE +1 -1
- data/README.markdown +33 -38
- data/Rakefile +24 -34
- data/TODO.markdown +3 -0
- data/VERSION +1 -1
- data/bin/revenc +30 -13
- data/config/cucumber.yml +4 -3
- data/examples/rsync/encrypted_data/key/encfs6.xml +27 -27
- data/examples/rsync/revenc.conf +2 -2
- data/examples/simple/encfs6.xml +27 -27
- data/features/app.feature +17 -17
- data/features/bin.feature +6 -6
- data/features/configuration.feature +9 -9
- data/features/copy.feature +15 -12
- data/features/generator.feature +1 -1
- data/features/mount.feature +14 -14
- data/features/settings.feature +119 -0
- data/features/step_definitions/revenc_steps.rb +1 -2
- data/features/support/aruba.rb +9 -9
- data/features/support/env.rb +8 -2
- data/features/unmount.feature +8 -8
- data/lib/revenc.rb +12 -3
- data/lib/revenc/app.rb +27 -53
- data/lib/revenc/core/array.rb +11 -0
- data/lib/revenc/core/hash.rb +45 -0
- data/lib/revenc/encfs_wrapper.rb +20 -24
- data/lib/revenc/errors.rb +3 -3
- data/lib/revenc/io.rb +13 -13
- data/lib/revenc/settings.rb +98 -0
- data/revenc.gemspec +28 -17
- data/spec/aruba_helper.rb +25 -0
- data/spec/basic_app/array_spec.rb +48 -0
- data/spec/basic_gem/aruba_helper_spec.rb +33 -0
- data/spec/basic_gem/basic_gem_spec.rb +71 -1
- data/spec/basic_gem/gemspec_spec.rb +68 -0
- data/spec/revenc/error_spec.rb +2 -2
- data/spec/revenc/io_spec.rb +12 -12
- data/spec/spec_helper.rb +4 -9
- data/spec/watchr.rb +48 -26
- metadata +120 -177
- data/.yardopts +0 -6
- data/spec/spec.opts +0 -2
data/lib/revenc/encfs_wrapper.rb
CHANGED
@@ -9,21 +9,18 @@ def initialize(base_dir, options)
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def mount(source=nil, mount_point_folder=nil)
|
12
|
+
mount_point_options = @options || {}
|
13
|
+
mount_point_options = mount_point_options.merge(@options[:mount].dup) if @options[:mount]
|
12
14
|
|
13
15
|
# add params from config file if not specified
|
14
|
-
source =
|
15
|
-
mount_point_folder =
|
16
|
+
source = (mount_point_options[:source] ? mount_point_options[:source][:name] : nil) unless source
|
17
|
+
mount_point_folder = (mount_point_options[:mountpoint] ? mount_point_options[:mountpoint][:name] : nil) unless mount_point_folder
|
16
18
|
|
17
19
|
# sanity check params
|
18
20
|
raise "source folder not specified" unless source
|
19
21
|
raise "mountpoint not specified" unless mount_point_folder
|
20
22
|
|
21
|
-
|
22
|
-
mount_point_options = mount_point_options.merge(:keyfile => configatron.mount.keyfile.name)
|
23
|
-
mount_point_options = mount_point_options.merge(:cmd => configatron.mount.cmd) if configatron.mount.cmd
|
24
|
-
mount_point_options = mount_point_options.merge(:executable => configatron.mount.executable) if configatron.mount.executable
|
25
|
-
|
26
|
-
mount_point = MountPoint.new(mount_point_folder, source, mount_point_options)
|
23
|
+
mount_point = MountPoint.new(mount_point_folder, source, mount_point_options.merge(@options))
|
27
24
|
|
28
25
|
if @options[:verbose]
|
29
26
|
puts "mount: source=#{mount_point.source.name}".cyan
|
@@ -38,18 +35,18 @@ def mount(source=nil, mount_point_folder=nil)
|
|
38
35
|
end
|
39
36
|
|
40
37
|
def unmount(foldername = nil)
|
41
|
-
|
38
|
+
unmount_point_options = @options || {}
|
39
|
+
unmount_point_options = unmount_point_options.merge(@options[:unmount].dup) if @options[:unmount]
|
40
|
+
mount_point_options = @options[:mount] ? @options[:mount].dup : {}
|
41
|
+
|
42
42
|
# add param from config file if not specified, try specific unmount
|
43
|
-
foldername =
|
43
|
+
foldername = (unmount_point_options[:mountpoint] ? unmount_point_options[:mountpoint][:name] : nil) unless foldername
|
44
44
|
# fallback to mount.mountpoint if specified
|
45
|
-
foldername =
|
46
|
-
|
45
|
+
foldername = (mount_point_options[:mountpoint] ? mount_point_options[:mountpoint][:name] : nil) unless foldername
|
46
|
+
|
47
47
|
# sanity check params
|
48
48
|
raise "mountpoint not specified" unless foldername
|
49
49
|
|
50
|
-
unmount_point_options = @options || {}
|
51
|
-
unmount_point_options = unmount_point_options.merge(:cmd => configatron.unmount.cmd) if configatron.umount.cmd
|
52
|
-
unmount_point_options = unmount_point_options.merge(:executable => configatron.unmount.executable) if configatron.umount.executable
|
53
50
|
unmount_point = UnmountPoint.new(foldername, unmount_point_options)
|
54
51
|
|
55
52
|
if @options[:verbose]
|
@@ -62,23 +59,22 @@ def unmount(foldername = nil)
|
|
62
59
|
end
|
63
60
|
|
64
61
|
def copy(source=nil, destination=nil)
|
62
|
+
copy_options = @options || {}
|
63
|
+
copy_options = copy_options.merge(@options[:copy].dup) if @options[:copy]
|
64
|
+
mount_point_options = @options[:mount] ? @options[:mount].dup : {}
|
65
65
|
|
66
66
|
# add params from config file if not specified
|
67
|
-
source =
|
67
|
+
source = (copy_options[:source] ? copy_options[:source][:name] : nil) unless source
|
68
68
|
# fallback
|
69
|
-
source =
|
70
|
-
destination =
|
69
|
+
source = (mount_point_options[:mountpoint] ? mount_point_options[:mountpoint][:name] : nil) unless source
|
70
|
+
destination = (copy_options[:destination] ? copy_options[:destination][:name] : nil) unless destination
|
71
71
|
|
72
72
|
# sanity check params
|
73
73
|
raise "source folder not specified" unless source
|
74
74
|
raise "destination not specified" unless destination
|
75
75
|
|
76
|
-
copy_options =
|
77
|
-
|
78
|
-
copy_options = copy_options.merge(:executable => configatron.copy.executable) if configatron.copy.executable
|
79
|
-
copy_options = copy_options.merge(:mountpoint => configatron.mount.mountpoint.name) if configatron.mount.mountpoint.name
|
80
|
-
|
81
|
-
copy_folder = CopySourceFolder.new( source, destination, copy_options)
|
76
|
+
copy_options = copy_options.merge(:mountpoint => mount_point_options[:mountpoint][:name]) if mount_point_options[:mountpoint]
|
77
|
+
copy_folder = CopySourceFolder.new(source, destination, copy_options)
|
82
78
|
|
83
79
|
if @options[:verbose]
|
84
80
|
puts "copy: source=#{copy_folder.name}".cyan
|
data/lib/revenc/errors.rb
CHANGED
@@ -20,7 +20,7 @@ def add(error_on, message = "Unknown error")
|
|
20
20
|
error_on_str = error_on_str.gsub(/_/, ' ')
|
21
21
|
error_on_str = error_on_str.gsub(/^revenc/, '').strip
|
22
22
|
#error_on_str = error_on_str.capitalize
|
23
|
-
|
23
|
+
|
24
24
|
@errors[error_on_str] ||= []
|
25
25
|
@errors[error_on_str] << message.to_s
|
26
26
|
end
|
@@ -28,7 +28,7 @@ def add(error_on, message = "Unknown error")
|
|
28
28
|
def empty?
|
29
29
|
@errors.empty?
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
def clear
|
33
33
|
@errors = {}
|
34
34
|
end
|
@@ -40,7 +40,7 @@ def each
|
|
40
40
|
def size
|
41
41
|
@errors.values.inject(0) { |error_count, attribute| error_count + attribute.size }
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
alias_method :count, :size
|
45
45
|
alias_method :length, :size
|
46
46
|
|
data/lib/revenc/io.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'mutagem'
|
2
|
+
require 'erb'
|
2
3
|
|
3
4
|
module Revenc
|
4
5
|
|
@@ -61,7 +62,6 @@ def system_cmd(cmd=nil)
|
|
61
62
|
system cmd
|
62
63
|
end
|
63
64
|
|
64
|
-
# Runs the YAML file through ERB
|
65
65
|
def render(value, b = binding)
|
66
66
|
ERB.new(value).result(b)
|
67
67
|
end
|
@@ -91,7 +91,7 @@ def empty?
|
|
91
91
|
contents = nil
|
92
92
|
File.open(@name, "r") do |f|
|
93
93
|
contents = f.read
|
94
|
-
end
|
94
|
+
end
|
95
95
|
contents.empty?
|
96
96
|
end
|
97
97
|
|
@@ -108,7 +108,7 @@ def initialize(name='passphrase', options={})
|
|
108
108
|
end
|
109
109
|
|
110
110
|
def validate
|
111
|
-
super
|
111
|
+
super
|
112
112
|
errors.add(self, "is empty") if empty?
|
113
113
|
end
|
114
114
|
end
|
@@ -120,7 +120,7 @@ def initialize(name='encfs6.xml', options={})
|
|
120
120
|
end
|
121
121
|
|
122
122
|
def validate
|
123
|
-
super
|
123
|
+
super
|
124
124
|
errors.add(self, "is empty") if exists? && empty?
|
125
125
|
end
|
126
126
|
end
|
@@ -155,8 +155,8 @@ class ActionFolder < FileFolder
|
|
155
155
|
|
156
156
|
def initialize(name=nil, options={})
|
157
157
|
super
|
158
|
-
@passphrasefile = PassphraseFile.new(options[:passphrasefile])
|
159
|
-
@keyfile = KeyFile.new(options[:keyfile])
|
158
|
+
@passphrasefile = PassphraseFile.new(options[:passphrasefile] ? options[:passphrasefile][:name] : nil)
|
159
|
+
@keyfile = KeyFile.new(options[:keyfile] ? options[:keyfile][:name] : nil)
|
160
160
|
@cmd = options[:cmd]
|
161
161
|
@executable = options[:executable]
|
162
162
|
end
|
@@ -177,17 +177,17 @@ def executable
|
|
177
177
|
# run the action if valid and return true if successful
|
178
178
|
def execute
|
179
179
|
raise errors.to_sentences unless valid?
|
180
|
-
|
180
|
+
|
181
181
|
# default failing command
|
182
182
|
result = false
|
183
|
-
|
183
|
+
|
184
184
|
# protect command from recursion
|
185
185
|
mutex = Mutagem::Mutex.new('revenc.lck')
|
186
|
-
|
186
|
+
lock_successful = mutex.execute do
|
187
187
|
result = system_cmd(cmd)
|
188
188
|
end
|
189
|
-
|
190
|
-
raise "action failed, lock file present" unless
|
189
|
+
|
190
|
+
raise "action failed, lock file present" unless lock_successful
|
191
191
|
result
|
192
192
|
end
|
193
193
|
end
|
@@ -225,7 +225,7 @@ def initialize(name=nil, options={})
|
|
225
225
|
@cmd = options[:cmd] || "<%= executable %> -u <%= mountpoint.name %>"
|
226
226
|
@executable = options[:executable] || 'fusermount'
|
227
227
|
end
|
228
|
-
|
228
|
+
|
229
229
|
# allow clarity in config files, instead of <%= name %> you can use <%= mountpoint.name %>
|
230
230
|
def mountpoint
|
231
231
|
self
|
@@ -247,7 +247,7 @@ def initialize(name=nil, destination_name=nil, options={})
|
|
247
247
|
@cmd = options[:cmd] || "<%= executable %> -r <%= source.name %> <%= destination.name %>"
|
248
248
|
@executable = options[:executable] || 'cp'
|
249
249
|
end
|
250
|
-
|
250
|
+
|
251
251
|
# allow clarity in config files, instead of <%= name %> you can use <%= source.name %>
|
252
252
|
def source
|
253
253
|
self
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Revenc
|
4
|
+
|
5
|
+
class Settings
|
6
|
+
|
7
|
+
def initialize(working_dir, options={})
|
8
|
+
@working_dir = working_dir
|
9
|
+
@options = options
|
10
|
+
configure
|
11
|
+
end
|
12
|
+
|
13
|
+
def options
|
14
|
+
@options
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
# read options from YAML config
|
20
|
+
def configure
|
21
|
+
|
22
|
+
# config file default options
|
23
|
+
configuration = {
|
24
|
+
:options => {
|
25
|
+
:verbose => false,
|
26
|
+
:coloring => 'AUTO'
|
27
|
+
},
|
28
|
+
:mount => {
|
29
|
+
:source => {
|
30
|
+
:name => nil
|
31
|
+
},
|
32
|
+
:mountpoint => {
|
33
|
+
:name => nil
|
34
|
+
},
|
35
|
+
:passphrasefile => {
|
36
|
+
:name => 'passphrase'
|
37
|
+
},
|
38
|
+
:keyfile => {
|
39
|
+
:name => 'encfs6.xml'
|
40
|
+
},
|
41
|
+
:cmd => nil,
|
42
|
+
:executable => nil
|
43
|
+
},
|
44
|
+
:unmount => {
|
45
|
+
:mountpoint => {
|
46
|
+
:name => nil
|
47
|
+
},
|
48
|
+
:cmd => nil,
|
49
|
+
:executable => nil
|
50
|
+
},
|
51
|
+
:copy => {
|
52
|
+
:source => {
|
53
|
+
:name => nil
|
54
|
+
},
|
55
|
+
:destination => {
|
56
|
+
:name => nil
|
57
|
+
},
|
58
|
+
:cmd => nil,
|
59
|
+
:executable => nil
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
# set default config if not given on command line
|
64
|
+
config = @options[:config]
|
65
|
+
unless config
|
66
|
+
config = [
|
67
|
+
File.join(@working_dir, "revenc.conf"),
|
68
|
+
File.join(@working_dir, ".revenc.conf"),
|
69
|
+
File.join(@working_dir, "config", "revenc.conf"),
|
70
|
+
File.expand_path(File.join("~", ".revenc.conf"))
|
71
|
+
].detect { |filename| File.exists?(filename) }
|
72
|
+
end
|
73
|
+
|
74
|
+
if config && File.exists?(config)
|
75
|
+
# rewrite options full path for config for later use
|
76
|
+
@options[:config] = config
|
77
|
+
|
78
|
+
# load options from the config file, overwriting hard-coded defaults
|
79
|
+
config_contents = YAML::load(File.open(config))
|
80
|
+
configuration.merge!(config_contents.symbolize_keys!) if config_contents && config_contents.is_a?(Hash)
|
81
|
+
else
|
82
|
+
# user specified a config file?, no error if user did not specify config file
|
83
|
+
raise "config file not found" if @options[:config]
|
84
|
+
end
|
85
|
+
|
86
|
+
# the command line options override options read from the config file
|
87
|
+
@options = configuration[:options].merge!(@options)
|
88
|
+
@options.symbolize_keys!
|
89
|
+
|
90
|
+
# mount, unmount and copy configuration hashes
|
91
|
+
@options[:mount] = configuration[:mount].recursively_symbolize_keys! if configuration[:mount]
|
92
|
+
@options[:unmount] = configuration[:unmount].recursively_symbolize_keys! if configuration[:unmount]
|
93
|
+
@options[:copy] = configuration[:copy].recursively_symbolize_keys! if configuration[:copy]
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
data/revenc.gemspec
CHANGED
@@ -1,10 +1,25 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
#
|
3
3
|
#
|
4
|
-
|
5
4
|
Gem::Specification.new do |s|
|
5
|
+
|
6
|
+
# avoid shelling out to run git every time the gemspec is evaluated
|
7
|
+
#
|
8
|
+
# @see spec/gemspec_spec.rb
|
9
|
+
#
|
10
|
+
gemfiles_cache = File.join(File.dirname(__FILE__), '.gemfiles')
|
11
|
+
if File.exists?(gemfiles_cache)
|
12
|
+
gemfiles = File.open(gemfiles_cache, "r") {|f| f.read}
|
13
|
+
# normalize EOL
|
14
|
+
gemfiles.gsub!(/\r\n/, "\n")
|
15
|
+
else
|
16
|
+
# .gemfiles missing, run 'rake gemfiles' to create it
|
17
|
+
# falling back to 'git ls-files'"
|
18
|
+
gemfiles = `git ls-files`
|
19
|
+
end
|
20
|
+
|
6
21
|
s.name = "revenc"
|
7
|
-
s.version = File.open(File.join(File.dirname(__FILE__),
|
22
|
+
s.version = File.open(File.join(File.dirname(__FILE__), 'VERSION'), "r") { |f| f.read }
|
8
23
|
s.platform = Gem::Platform::RUBY
|
9
24
|
s.authors = ["Robert Wahler"]
|
10
25
|
s.email = ["robert@gearheadforhire.com"]
|
@@ -17,26 +32,22 @@ Gem::Specification.new do |s|
|
|
17
32
|
|
18
33
|
s.add_dependency 'mutagem', '>= 0.1.3'
|
19
34
|
s.add_dependency 'term-ansicolor', '>= 1.0.4'
|
20
|
-
s.add_dependency 'configatron', '>= 2.5.1'
|
21
35
|
|
22
|
-
s.add_development_dependency "bundler", ">= 1.0.
|
23
|
-
s.add_development_dependency "rspec", ">=
|
24
|
-
s.add_development_dependency "cucumber", "
|
25
|
-
s.add_development_dependency "aruba", "
|
36
|
+
s.add_development_dependency "bundler", ">= 1.0.14"
|
37
|
+
s.add_development_dependency "rspec", ">= 2.6.0"
|
38
|
+
s.add_development_dependency "cucumber", "~> 1.0"
|
39
|
+
s.add_development_dependency "aruba", "~> 0.4.2"
|
26
40
|
s.add_development_dependency "rake", ">= 0.8.7"
|
27
|
-
s.add_development_dependency "yard", ">= 0.6.1"
|
28
|
-
s.add_development_dependency "rdiscount", ">= 1.6.5"
|
29
41
|
|
30
|
-
s.files =
|
31
|
-
s.executables =
|
32
|
-
s.
|
33
|
-
s.require_path = 'lib'
|
42
|
+
s.files = gemfiles.split("\n")
|
43
|
+
s.executables = gemfiles.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
44
|
+
s.require_paths = ["lib"]
|
34
45
|
|
35
46
|
s.has_rdoc = 'yard'
|
36
|
-
s.rdoc_options = [
|
37
|
-
'--title', 'Revenc Documentation',
|
38
|
-
'--main', 'README.markdown',
|
47
|
+
s.rdoc_options = [
|
48
|
+
'--title', 'Revenc Documentation',
|
49
|
+
'--main', 'README.markdown',
|
39
50
|
'--line-numbers',
|
40
|
-
'--inline-source'
|
51
|
+
'--inline-source'
|
41
52
|
]
|
42
53
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Aruba
|
2
|
+
module Api
|
3
|
+
|
4
|
+
# @return full path to files in the aruba tmp folder
|
5
|
+
def fullpath(filename)
|
6
|
+
path = File.expand_path(File.join(current_dir, filename))
|
7
|
+
if path.match(/^\/cygdrive/)
|
8
|
+
# match /cygdrive/c/path/to and return c:\\path\\to
|
9
|
+
path = `cygpath -w #{path}`.chomp
|
10
|
+
elsif path.match(/.\:/)
|
11
|
+
# match c:/path/to and return c:\\path\\to
|
12
|
+
path = path.gsub(/\//, '\\')
|
13
|
+
end
|
14
|
+
path
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return the contents of "filename" in the aruba tmp folder
|
18
|
+
def get_file_contents(filename)
|
19
|
+
in_current_dir do
|
20
|
+
IO.read(filename)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Array do
|
4
|
+
|
5
|
+
describe 'recursively_symbolize_keys!' do
|
6
|
+
|
7
|
+
it "should recursively convert a hash with string keys to a hash with symbol keys" do
|
8
|
+
hash_symbols = {
|
9
|
+
:options => {
|
10
|
+
:verbose => false,
|
11
|
+
},
|
12
|
+
:repos => {
|
13
|
+
:repo1 => {:path => "something"}
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
hash_strings = {
|
18
|
+
'options' => {
|
19
|
+
'verbose' => false,
|
20
|
+
},
|
21
|
+
'repos' => {
|
22
|
+
'repo1' => {'path' => "something"}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
hash_symbols.should == hash_strings.recursively_symbolize_keys!
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should should handle hashes that are already symbolized" do
|
30
|
+
hash_symbols = {
|
31
|
+
:options => {
|
32
|
+
:verbose => false,
|
33
|
+
},
|
34
|
+
:repos => {
|
35
|
+
:repo1 => {:path => "something"}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
hash_copy = hash_symbols.dup
|
40
|
+
|
41
|
+
hash_copy.should == hash_symbols.recursively_symbolize_keys!
|
42
|
+
hash_symbols[:repos][:repo1].should == {:path => "something"}
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Revenc do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@filename = 'input.txt'
|
7
|
+
write_file(@filename, "the quick brown fox")
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'Aruba::API.current_dir' do
|
11
|
+
|
12
|
+
it "should return the current dir as 'tmp/aruba'" do
|
13
|
+
current_dir.should match(/^tmp\/aruba$/)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "aruba_helper fullpath('input.txt')" do
|
18
|
+
|
19
|
+
it "should return a valid expanded path to 'input.txt'" do
|
20
|
+
path = fullpath('input.txt')
|
21
|
+
path.should match(/tmp..*aruba/)
|
22
|
+
File.exists?(path).should == true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "aruba_helper get_file_contents('input.txt')" do
|
27
|
+
|
28
|
+
it "should return the contents of 'input.txt' as a String" do
|
29
|
+
get_file_contents('input.txt').should == 'the quick brown fox'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|