revenc 0.1.3 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. data/.gemfiles +53 -0
  2. data/.gitignore +4 -8
  3. data/Gemfile.lock +42 -37
  4. data/HISTORY.markdown +9 -2
  5. data/LICENSE +1 -1
  6. data/README.markdown +33 -38
  7. data/Rakefile +24 -34
  8. data/TODO.markdown +3 -0
  9. data/VERSION +1 -1
  10. data/bin/revenc +30 -13
  11. data/config/cucumber.yml +4 -3
  12. data/examples/rsync/encrypted_data/key/encfs6.xml +27 -27
  13. data/examples/rsync/revenc.conf +2 -2
  14. data/examples/simple/encfs6.xml +27 -27
  15. data/features/app.feature +17 -17
  16. data/features/bin.feature +6 -6
  17. data/features/configuration.feature +9 -9
  18. data/features/copy.feature +15 -12
  19. data/features/generator.feature +1 -1
  20. data/features/mount.feature +14 -14
  21. data/features/settings.feature +119 -0
  22. data/features/step_definitions/revenc_steps.rb +1 -2
  23. data/features/support/aruba.rb +9 -9
  24. data/features/support/env.rb +8 -2
  25. data/features/unmount.feature +8 -8
  26. data/lib/revenc.rb +12 -3
  27. data/lib/revenc/app.rb +27 -53
  28. data/lib/revenc/core/array.rb +11 -0
  29. data/lib/revenc/core/hash.rb +45 -0
  30. data/lib/revenc/encfs_wrapper.rb +20 -24
  31. data/lib/revenc/errors.rb +3 -3
  32. data/lib/revenc/io.rb +13 -13
  33. data/lib/revenc/settings.rb +98 -0
  34. data/revenc.gemspec +28 -17
  35. data/spec/aruba_helper.rb +25 -0
  36. data/spec/basic_app/array_spec.rb +48 -0
  37. data/spec/basic_gem/aruba_helper_spec.rb +33 -0
  38. data/spec/basic_gem/basic_gem_spec.rb +71 -1
  39. data/spec/basic_gem/gemspec_spec.rb +68 -0
  40. data/spec/revenc/error_spec.rb +2 -2
  41. data/spec/revenc/io_spec.rb +12 -12
  42. data/spec/spec_helper.rb +4 -9
  43. data/spec/watchr.rb +48 -26
  44. metadata +120 -177
  45. data/.yardopts +0 -6
  46. data/spec/spec.opts +0 -2
@@ -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 = configatron.mount.source.name unless source
15
- mount_point_folder = configatron.mount.mountpoint.name unless 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
- mount_point_options = @options.merge(:passphrasefile => configatron.mount.passphrasefile.name)
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 = configatron.unmount.mountpoint.name unless 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 = configatron.mount.mountpoint.name unless 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 = configatron.copy.source.name unless source
67
+ source = (copy_options[:source] ? copy_options[:source][:name] : nil) unless source
68
68
  # fallback
69
- source = configatron.mount.mountpoint.name unless source
70
- destination = configatron.copy.destination.name unless 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 = @options || {}
77
- copy_options = copy_options.merge(:cmd => configatron.copy.cmd) if configatron.copy.cmd
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
@@ -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
 
@@ -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
- lock_sucessful = mutex.execute do
186
+ lock_successful = mutex.execute do
187
187
  result = system_cmd(cmd)
188
188
  end
189
-
190
- raise "action failed, lock file present" unless lock_sucessful
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
@@ -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__), *%w[VERSION]), "r") { |f| f.read }
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.0"
23
- s.add_development_dependency "rspec", ">= 1.2.9"
24
- s.add_development_dependency "cucumber", ">= 0.6"
25
- s.add_development_dependency "aruba", ">= 0.2.0"
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 = `git ls-files`.split("\n")
31
- s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
32
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
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