boxafe 0.1.5 → 0.1.6

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.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NmRhNGVkMDIxZjM2MjUyYTVhYTcxZDU5NDUwNzJhMWY3YjcxZTcxYw==
5
- data.tar.gz: !binary |-
6
- MGUzZWM0OWE1NThjN2U0ZmJlNzNkM2RkMDQ3MDU3YzU0N2RhMTBmNQ==
2
+ SHA1:
3
+ metadata.gz: 0ec42509d2649ac10f34b88c74cbcc89f0b3a490
4
+ data.tar.gz: 300e6ec0476dd393b182496f670f14adce0ef1ef
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- MGY5MTBjNDBmOTRmMTQ3NGM3NDAwMzQ1NDUyMzg1ODI3ODNiZTM5MjI5MTc3
10
- ZWRkYzI5ZTNiMGVmOTFmMzI5ZTU1NjUyMjMwY2EwNTBmYjMzNzNhZjNmZGY1
11
- MDAwNWQ4MGUzOTgzZTVkNDZlZDljNjg3YzI2NzAxZGVjNWMzZTY=
12
- data.tar.gz: !binary |-
13
- ZTc0ODMyYWQzYTU3Zjc5Mzg4OWI3YmY3NTQ4YWM3OGU1YjU5OTIxMzQ4NDI2
14
- ZTk2ODVjM2JiMjgyNjllMzI5ZjY3Yzc5ZWY1YmRhZDNhNmU1YjMxYzI5MDE3
15
- OWVjMjkwYTg4NDYzNjM2ZTllMWJlZWE5ODNlMzdiZGE4YjI4OWY=
6
+ metadata.gz: a964d47710fefebe84c427815fe41f64626f25b286ea9598b6594fbdfa8cffa667d81747758fad249c75e8742ff5f2d4725d5e42d4cdcc4d057d92b9ffc2cbe6
7
+ data.tar.gz: acbe692fcf9263e0979b6c0f3040c735ab9058eb08cbc151a2db530522bb30b9792cb9243add6014eb7d46469f150158cccc52be1bb8403f7df3f433e3cdc19e
data/Gemfile CHANGED
@@ -4,15 +4,12 @@ source "http://rubygems.org"
4
4
  # gem "activesupport", ">= 2.3.5"
5
5
 
6
6
  gem 'paint', '~> 0.8.5'
7
- gem 'commander', '~> 4.1.2'
7
+ gem 'commander', '~> 4.2.1'
8
8
  gem 'which_works', '~> 1.0.0'
9
- gem 'dotenv', '~> 0.8.0'
9
+ gem 'dotenv', '~> 1.0.2'
10
10
  gem 'mutaconf', '~> 0.2.0'
11
- gem 'launchdr', '3'
12
- gem 'growl', '~> 1.0.3'
13
- gem 'terminal-notifier-guard', '~> 1.5.3'
14
- #gem 'whenever', '~> 0.8.2'
15
- #gem 'whenever', :git => 'git@github.com:AlphaHydrae/whenever.git', :branch => 'block-config'
11
+ gem 'notifies', '~> 0.1.0'
12
+ gem 'multi_scheduler', '~> 0.1.2'
16
13
 
17
14
  # Add dependencies to develop your gem here.
18
15
  # Include everything needed to run rake, tests, features, etc.
@@ -26,4 +23,5 @@ group :development do
26
23
  gem 'rake-version'
27
24
  gem 'simplecov'
28
25
  gem 'fakefs', require: 'fakefs/safe'
26
+ gem 'coveralls', require: false
29
27
  end
data/README.md CHANGED
@@ -3,6 +3,7 @@
3
3
  [![Gem Version](https://badge.fury.io/rb/boxafe.png)](http://badge.fury.io/rb/boxafe)
4
4
  [![Dependency Status](https://gemnasium.com/AlphaHydrae/boxafe.png)](https://gemnasium.com/AlphaHydrae/boxafe)
5
5
  [![Build Status](https://secure.travis-ci.org/AlphaHydrae/boxafe.png)](http://travis-ci.org/AlphaHydrae/boxafe)
6
+ [![Coverage Status](https://coveralls.io/repos/AlphaHydrae/boxafe/badge.png?branch=master)](https://coveralls.io/r/AlphaHydrae/boxafe?branch=master)
6
7
 
7
8
  Boxafe mounts EncFS filesystems or "boxes" that you define in a configuration file with a friendly DSL.
8
9
  It can also mount them on startup. [EncFS](http://www.arg0.net/encfs) must be installed separately.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.5
1
+ 0.1.6
data/lib/boxafe/box.rb CHANGED
@@ -1,115 +1,81 @@
1
1
  # encoding: UTF-8
2
2
  require 'fileutils'
3
3
 
4
- class Boxafe::Box
4
+ module Boxafe
5
5
 
6
- OPTION_KEYS = [ :name, :root, :mount, :volume, :encfs_config, :keychain, :password_file ]
6
+ class Box
7
+ OPTION_KEYS = [ :name, :root, :mount, :volume, :encfs_config, :keychain, :password_file ]
7
8
 
8
- def initialize options = {}
9
-
10
- raise Boxafe::Error, "The :name option is required" unless options[:name]
11
-
12
- @options = options
13
- end
9
+ def initialize options = {}
10
+ raise OptionError.new("The :name option is required", :name) unless options[:name]
11
+ @options = options
12
+ @validator = Validator.new raise_first: true
13
+ end
14
14
 
15
- def name
16
- @options[:name]
17
- end
15
+ def name
16
+ @options[:name]
17
+ end
18
18
 
19
- def mount
20
- system encfs.command
21
- end
19
+ def command
20
+ encfs.command
21
+ end
22
22
 
23
- def unmount
24
- opts = options
25
- result = system "#{opts[:umount]} #{opts[:mount]}"
26
- sleep opts[:umount_delay] if opts[:umount_delay] and opts[:umount_delay] > 0
27
- result
28
- end
23
+ def mount
24
+ @validator.validate mount_options
25
+ ensure_mount_point
26
+ system command
27
+ end
29
28
 
30
- def encfs
31
- Boxafe::Encfs.new options
32
- end
29
+ def unmount
30
+ options = mount_options
31
+ result = system "#{options[:umount]} #{options[:mount]}"
32
+ sleep options[:umount_delay] if options[:umount_delay] and options[:umount_delay] > 0
33
+ result
34
+ end
33
35
 
34
- def ensure_mount_point
35
- FileUtils.mkdir_p options[:mount]
36
- end
36
+ def mounted?
37
+ File.directory? mount_options[:mount]
38
+ end
37
39
 
38
- def description verbose = false
39
- opts = options
40
- String.new.tap do |s|
41
-
42
- s << Paint["## #{name}", :cyan, :bold]
43
- s << "\nEncrypted Root: "
44
- s << if File.directory?(opts[:root])
45
- Paint["#{opts[:root]}", :green]
46
- elsif File.exists?(opts[:root])
47
- Paint["#{opts[:root]} (not a directory)", :red]
48
- else
49
- Paint["#{opts[:root]} (doesn't exist)", :red]
40
+ def mount_options
41
+ default_mount_options.merge(@options).tap do |options|
42
+ options[:keychain] = @options[:name] if options[:keychain] == true
50
43
  end
44
+ end
51
45
 
52
- s << "\nMount Point: "
53
- s << case mount_status
54
- when :mounted
55
- Paint["#{opts[:mount]}", :green]
56
- when :invalid
57
- Paint["#{opts[:mount]} (not a directory)", :red]
58
- else
59
- Paint["#{opts[:mount]} (not mounted)", :yellow]
60
- end
46
+ def configure options = {}, &block
47
+ @options.merge! options
48
+ DSL.new(@options).instance_eval &block if block
49
+ self
50
+ end
61
51
 
62
- s << "\nVolume Name: #{opts[:volume]}"
63
- if opts[:password_file]
64
- s << "\nPassword File: #{opts[:password_file]}"
65
- elsif opts[:keychain]
66
- s << "\nKeychain Password: #{opts[:keychain]}"
67
- end
68
- s << "\nEncFS Config: #{opts[:encfs_config]}" if opts[:encfs_config]
52
+ private
69
53
 
70
- s << "\nCommand: #{Paint[encfs.command, :yellow]}" if verbose
54
+ def ensure_mount_point
55
+ FileUtils.mkdir_p mount_options[:mount]
71
56
  end
72
- end
73
57
 
74
- def mount_status
75
- if File.directory? options[:mount]
76
- :mounted
77
- elsif File.exists? options[:mount]
78
- :invalid
79
- else
80
- :unmounted
58
+ def encfs
59
+ Boxafe::Encfs.new mount_options
60
+ end
61
+
62
+ def default_mount_options
63
+ name = @options[:name]
64
+ {
65
+ # TODO: change default root and mount dirs depending on host os
66
+ root: "~/Dropbox/#{name}",
67
+ mount: "/Volumes/#{name}",
68
+ volume: name
69
+ }
81
70
  end
82
- end
83
-
84
- def configure options = {}, &block
85
- @options.merge! options
86
- DSL.new(@options).instance_eval &block if block
87
- self
88
- end
89
-
90
- def options
91
- @options.tap do |opts|
92
71
 
93
- opts[:root] = File.expand_path opts[:root] || "~/Dropbox/#{opts[:name]}"
94
- opts[:mount] = File.expand_path opts[:mount] || "/Volumes/#{opts[:name]}"
95
- opts[:encfs_config] = File.expand_path opts[:encfs_config] if opts[:encfs_config]
96
- opts[:volume] ||= opts[:name]
72
+ class DSL
97
73
 
98
- if opts[:password_file]
99
- opts[:password_file] = File.expand_path opts[:password_file]
100
- opts.delete :keychain
101
- elsif opts[:keychain] == true
102
- opts[:keychain] = opts[:name]
74
+ def initialize options
75
+ @options = options
103
76
  end
104
- end
105
- end
106
77
 
107
- class DSL
108
-
109
- def initialize options
110
- @options = options
78
+ OPTION_KEYS.each{ |name| define_method(name){ |value| @options[name] = value } }
111
79
  end
112
-
113
- OPTION_KEYS.each{ |name| define_method(name){ |value| @options[name] = value } }
114
80
  end
115
81
  end
data/lib/boxafe/cli.rb CHANGED
@@ -1,14 +1,18 @@
1
1
  # encoding: UTF-8
2
+ require 'notifies'
3
+ require 'multi_scheduler'
4
+ require 'which_works'
5
+
2
6
  class Boxafe::CLI
3
7
 
4
8
  def start options = {}
5
9
  # TODO: allow to mount only specific boxes
6
10
  # TODO: only allow boxes with an extpass
7
- Boxafe::Scheduler.platform_scheduler(options).start
11
+ schedule(options).start
8
12
  end
9
13
 
10
14
  def stop options = {}
11
- Boxafe::Scheduler.platform_scheduler(options).stop
15
+ schedule(options).stop
12
16
  end
13
17
 
14
18
  def status options = {}
@@ -16,11 +20,11 @@ class Boxafe::CLI
16
20
  config = load_config options
17
21
 
18
22
  puts
19
- puts Paint["# Boxafe v#{Boxafe::VERSION}", :bold]
23
+ puts global_description(config, options[:verbose])
20
24
 
21
25
  config.boxes.each do |box|
22
26
  puts
23
- puts box.description(options[:verbose])
27
+ puts box_description(box, options[:verbose])
24
28
  end
25
29
 
26
30
  puts
@@ -34,33 +38,31 @@ class Boxafe::CLI
34
38
  # FIXME: crashes with unknown box names
35
39
  boxes = args.empty? ? config.boxes : args.collect{ |arg| config.boxes.find{ |box| box.name == arg } }
36
40
 
37
- notifier = Boxafe::Notifier.notifier config.options
38
-
39
41
  puts
40
42
  boxes.each do |box|
41
43
 
42
44
  print "Mounting #{box.name}... "
43
- case box.mount_status
44
- when :mounted
45
- notifier.notify "#{box.name} is already mounted" if notifier
45
+ if box.mounted?
46
+ notify :info, "#{box.name} is already mounted", config.options
46
47
  puts Paint['already mounted', :green]
47
48
  next
48
- when :invalid
49
- notifier.notify "#{box.name} has an invalid mount point (not a directory)", type: :failure if notifier
50
- puts Paint['invalid mount point (not a directory)', :red]
51
- next
52
49
  end
53
50
 
54
- box.ensure_mount_point
55
- box.mount
51
+ begin
52
+ box.mount
53
+ rescue OptionError => e
54
+ msg = ":#{e.option} option error - #{e.message}"
55
+ notify :error, "#{box.name} #{msg}", config.options
56
+ puts Paint[msg, :red]
57
+ next
58
+ end
56
59
 
57
- puts case box.mount_status
58
- when :mounted
59
- notifier.notify "#{box.name} is mounted", type: :success if notifier
60
- Paint['mounted', :green]
60
+ if box.mounted?
61
+ notify :ok, "#{box.name} is mounted", config.options
62
+ puts Paint['mounted', :green]
61
63
  else
62
- notifier.notify "#{box.name} could not be mounted", type: :failure if notifier
63
- Paint['could not be mounted', :red]
64
+ notify :error, "#{box.name} could not be mounted", config.options
65
+ puts Paint['could not be mounted', :red]
64
66
  end
65
67
  end
66
68
 
@@ -80,11 +82,10 @@ class Boxafe::CLI
80
82
  print "Umounting #{box.name}... "
81
83
  box.unmount
82
84
 
83
- puts case box.mount_status
84
- when :unmounted
85
- Paint['unmounted', :green]
85
+ if box.mounted?
86
+ puts Paint['could not be unmounted', :red]
86
87
  else
87
- Paint['could not be unmounted', :red]
88
+ puts Paint['unmounted', :green]
88
89
  end
89
90
  end
90
91
 
@@ -93,7 +94,83 @@ class Boxafe::CLI
93
94
 
94
95
  private
95
96
 
97
+ def schedule options = {}
98
+ MultiScheduler.schedule 'com.alphahydrae.boxafe', command: 'boxafe', args: %w(mount)
99
+ end
100
+
101
+ def global_description config, verbose = false
102
+
103
+ Array.new.tap do |a|
104
+
105
+ a << Paint["Boxafe v#{Boxafe::VERSION}", :bold]
106
+ # TODO: show notifications status
107
+
108
+ if verbose
109
+
110
+ encfs_bin, umount_bin = config.options[:encfs], config.options[:umount]
111
+ errors = Boxafe::Validator.new.validate_global_options config.options
112
+
113
+ a << "EncFS binary: #{option_value :encfs, encfs_bin, errors}"
114
+ a << "umount binary: #{option_value :umount, umount_bin, errors}"
115
+ # TODO: show umount delay if verbose
116
+ end
117
+ end.join "\n"
118
+ end
119
+
120
+ def box_description box, verbose = false
121
+
122
+ options = box.mount_options
123
+ errors = Boxafe::Validator.new.validate_mount_options options
124
+
125
+ root_str = option_value :root, options[:root], errors
126
+ mount_str = option_value :mount, options[:mount], errors, box.mounted? ? nil : "not mounted"
127
+
128
+ if options[:verbose]
129
+
130
+ Array.new.tap do |a|
131
+
132
+ a << Paint["## #{box.name}", :cyan, :bold]
133
+ a << "Encrypted Root: #{root_str}"
134
+ a << "Mount Point: #{mount_str}"
135
+ a << "Password File: #{option_value :password_file, options[:password_file], errors}" if options[:password_file]
136
+ a << "Keychain Password: #{option_value :keychain, options[:keychain], errors}" if options[:keychain]
137
+ a << "EncFS Config: #{option_value :encfs_config, options[:encfs_config], errors}" if options[:encfs_config]
138
+ a << "Command: #{Paint[box.command, :cyan]}" if verbose
139
+
140
+ errors.each do |e|
141
+ a << Paint[":#{e.option} option error - #{e.message}", :red]
142
+ end
143
+ end.join "\n"
144
+ else
145
+
146
+ String.new.tap do |s|
147
+
148
+ s << %|#{Paint["#{box.name}:", :bold, :cyan]} #{root_str} -> #{mount_str}|
149
+
150
+ errors.each do |e|
151
+ s << "\n" + " " * (box.name.length + 2)
152
+ s << Paint[":#{e.option} option error - #{e.message}", :red]
153
+ end
154
+ end
155
+ end
156
+ end
157
+
158
+ def option_value name, value, errors, warning = nil
159
+ if error = errors.find{ |e| e.option == name }
160
+ Paint[value, :red]
161
+ elsif warning
162
+ Paint["#{value} (#{warning})", :yellow]
163
+ else
164
+ Paint[value, :green]
165
+ end
166
+ end
167
+
96
168
  def load_config options = {}
97
169
  Boxafe::Config.new(options).load
98
170
  end
171
+
172
+ def notify type, msg, options = {}
173
+ return unless options[:notify]
174
+ Notifies.notify msg, type: type
175
+ end
99
176
  end
data/lib/boxafe/config.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  class Boxafe::Config
3
3
 
4
4
  # TODO: document unmount_delay
5
- # TODO: add option to chdir, boxes relative to home dir by default
5
+ # TODO: add option to chdir, boxes relative to working directory when calling start by default
6
6
  OPTION_KEYS = [ :encfs, :umount, :umount_delay, :notify ]
7
7
 
8
8
  attr_reader :boxes, :options
data/lib/boxafe/encfs.rb CHANGED
@@ -36,7 +36,7 @@ class Boxafe::Encfs
36
36
 
37
37
  def extpass
38
38
  if @options[:password_file]
39
- %|--extpass="head -n 1 #{Shellwords.escape @options[:password_file]}"|
39
+ %|--extpass="head -n 1 #{Shellwords.escape File.expand_path(@options[:password_file], Dir.pwd)}"|
40
40
  elsif @options[:keychain]
41
41
  %*--extpass="security 2>&1 >/dev/null find-generic-password -gl '#{@options[:keychain]}' |grep password|cut -d \\\\\\" -f 2"*
42
42
  else
@@ -23,7 +23,7 @@ class Boxafe::Program < Commander::Runner
23
23
  c.syntax = 'boxafe status'
24
24
  c.description = 'Display the current status and configuration'
25
25
  c.action do |args,options|
26
- to_trace_or_not_to_trace do
26
+ to_trace_or_not_to_trace options.trace do
27
27
  cli.status extract(options)
28
28
  end
29
29
  end
@@ -33,7 +33,7 @@ class Boxafe::Program < Commander::Runner
33
33
  c.syntax = 'boxafe mount'
34
34
  c.description = 'Mount configured boxes with EncFS'
35
35
  c.action do |args,options|
36
- to_trace_or_not_to_trace do
36
+ to_trace_or_not_to_trace options.trace do
37
37
  cli.mount *args
38
38
  end
39
39
  end
@@ -43,7 +43,7 @@ class Boxafe::Program < Commander::Runner
43
43
  c.syntax = 'boxafe unmount'
44
44
  c.description = 'Unmount configured boxes'
45
45
  c.action do |args,options|
46
- to_trace_or_not_to_trace do
46
+ to_trace_or_not_to_trace options.trace do
47
47
  cli.unmount *args
48
48
  end
49
49
  end
@@ -53,7 +53,7 @@ class Boxafe::Program < Commander::Runner
53
53
  c.syntax = 'boxafe start'
54
54
  c.description = 'Configure boxafe to run on startup'
55
55
  c.action do |args,options|
56
- to_trace_or_not_to_trace do
56
+ to_trace_or_not_to_trace options.trace do
57
57
  cli.start *(args.push extract(options))
58
58
  end
59
59
  end
@@ -63,11 +63,13 @@ class Boxafe::Program < Commander::Runner
63
63
  c.syntax = 'boxafe stop'
64
64
  c.description = 'Stop boxafe from running on startup'
65
65
  c.action do |args,options|
66
- to_trace_or_not_to_trace do
66
+ to_trace_or_not_to_trace options.trace do
67
67
  cli.stop *(args.push extract(options))
68
68
  end
69
69
  end
70
70
  end
71
+
72
+ default_command :status
71
73
  end
72
74
 
73
75
  private
@@ -77,12 +79,12 @@ class Boxafe::Program < Commander::Runner
77
79
  end
78
80
 
79
81
  def to_trace_or_not_to_trace trace = false
80
- begin
82
+ if trace
81
83
  yield
82
- rescue Boxafe::Error => e
83
- if trace
84
- raise e
85
- else
84
+ else
85
+ begin
86
+ yield
87
+ rescue Boxafe::Error => e
86
88
  warn Paint["#{e.message}#{BACKTRACE_NOTICE}", :red]
87
89
  exit e.code
88
90
  end
@@ -0,0 +1,70 @@
1
+
2
+ module Boxafe
3
+
4
+ class Validator
5
+
6
+ def initialize options = {}
7
+ @raise_first = options[:raise_first]
8
+ end
9
+
10
+ def validate options = {}
11
+ validate_global_options(options) + validate_mount_options(options)
12
+ end
13
+
14
+ def validate_global_options options = {}
15
+
16
+ errors = []
17
+ encfs_bin, umount_bin = options[:encfs], options[:umount]
18
+
19
+ add "could not find encfs binary '#{encfs_bin}'; is it in the PATH?", :encfs, errors unless Which.which encfs_bin
20
+ add "could not find umount binary '#{umount_bin}'; is it in the PATH?", :umount, errors unless Which.which umount_bin
21
+
22
+ errors
23
+ end
24
+
25
+ def validate_mount_options options = {}
26
+
27
+ errors = []
28
+
29
+ validate_file :root, 'root directory', options[:root], errors, required: true
30
+ validate_file :mount, 'mount directory', options[:mount], errors, required: true, presence: false
31
+ validate_file :password_file, 'password file', options[:password_file], errors, file: true
32
+ validate_file :config_file, 'config file', options[:config_file], errors, file: true
33
+
34
+ if options[:password_file] and options[:keychain]
35
+ add "cannot use both a password file and the keychain", :keychain, errors
36
+ end
37
+
38
+ errors
39
+ end
40
+
41
+ private
42
+
43
+ def validate_file option, name, file, errors, options = {}
44
+
45
+ file = file ? File.expand_path(file.to_s) : nil
46
+
47
+ if !file
48
+ add "#{name} is required", option, errors if options[:required]
49
+ elsif !File.exists?(file)
50
+ add "#{file} does not exist", option, errors if options[:presence] != false
51
+ elsif !options[:file] && !File.directory?(file)
52
+ add "#{file} is not a directory", option, errors
53
+ elsif options[:file] && !File.file?(file)
54
+ add "#{file} is not a file", option, errors
55
+ elsif options[:file] && !File.readable?(file)
56
+ add "#{file} is not readable by the current user", option, errors
57
+ end
58
+ end
59
+
60
+ def add msg, option = nil, errors = []
61
+ OptionError.new(msg, option).tap do |e|
62
+ if @raise_first
63
+ raise e
64
+ else
65
+ errors << e
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
data/lib/boxafe.rb CHANGED
@@ -4,7 +4,7 @@ require 'dotenv'
4
4
  require 'mutaconf'
5
5
 
6
6
  module Boxafe
7
- VERSION = '0.1.5'
7
+ VERSION = '0.1.6'
8
8
 
9
9
  # TODO: add detailed error description for non-trace mode
10
10
  class Error < StandardError
@@ -15,6 +15,15 @@ module Boxafe
15
15
  @code = code
16
16
  end
17
17
  end
18
+
19
+ class OptionError < Error
20
+ attr_reader :option
21
+
22
+ def initialize msg, option = nil
23
+ super msg
24
+ @option = option
25
+ end
26
+ end
18
27
  end
19
28
 
20
29
  Dir[File.join File.dirname(__FILE__), File.basename(__FILE__, '.*'), '*.rb'].each{ |lib| require lib }
metadata CHANGED
@@ -1,251 +1,251 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: boxafe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - AlphaHydrae
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-30 00:00:00.000000000 Z
11
+ date: 2014-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: paint
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: 0.8.5
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.8.5
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: commander
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 4.1.2
33
+ version: 4.2.1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 4.1.2
40
+ version: 4.2.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: which_works
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: 1.0.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 1.0.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: dotenv
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ~>
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.8.0
61
+ version: 1.0.2
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ~>
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.8.0
68
+ version: 1.0.2
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: mutaconf
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ~>
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
75
  version: 0.2.0
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ~>
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.2.0
83
83
  - !ruby/object:Gem::Dependency
84
- name: launchdr
84
+ name: notifies
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '='
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '3'
89
+ version: 0.1.0
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '='
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '3'
96
+ version: 0.1.0
97
97
  - !ruby/object:Gem::Dependency
98
- name: growl
98
+ name: multi_scheduler
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ~>
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 1.0.3
103
+ version: 0.1.2
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ~>
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 1.0.3
111
- - !ruby/object:Gem::Dependency
112
- name: terminal-notifier-guard
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ~>
116
- - !ruby/object:Gem::Version
117
- version: 1.5.3
118
- type: :runtime
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ~>
123
- - !ruby/object:Gem::Version
124
- version: 1.5.3
110
+ version: 0.1.2
125
111
  - !ruby/object:Gem::Dependency
126
112
  name: bundler
127
113
  requirement: !ruby/object:Gem::Requirement
128
114
  requirements:
129
- - - ! '>='
115
+ - - ">="
130
116
  - !ruby/object:Gem::Version
131
117
  version: '0'
132
118
  type: :development
133
119
  prerelease: false
134
120
  version_requirements: !ruby/object:Gem::Requirement
135
121
  requirements:
136
- - - ! '>='
122
+ - - ">="
137
123
  - !ruby/object:Gem::Version
138
124
  version: '0'
139
125
  - !ruby/object:Gem::Dependency
140
126
  name: rake
141
127
  requirement: !ruby/object:Gem::Requirement
142
128
  requirements:
143
- - - ! '>='
129
+ - - ">="
144
130
  - !ruby/object:Gem::Version
145
131
  version: '0'
146
132
  type: :development
147
133
  prerelease: false
148
134
  version_requirements: !ruby/object:Gem::Requirement
149
135
  requirements:
150
- - - ! '>='
136
+ - - ">="
151
137
  - !ruby/object:Gem::Version
152
138
  version: '0'
153
139
  - !ruby/object:Gem::Dependency
154
140
  name: rspec
155
141
  requirement: !ruby/object:Gem::Requirement
156
142
  requirements:
157
- - - ! '>='
143
+ - - ">="
158
144
  - !ruby/object:Gem::Version
159
145
  version: '0'
160
146
  type: :development
161
147
  prerelease: false
162
148
  version_requirements: !ruby/object:Gem::Requirement
163
149
  requirements:
164
- - - ! '>='
150
+ - - ">="
165
151
  - !ruby/object:Gem::Version
166
152
  version: '0'
167
153
  - !ruby/object:Gem::Dependency
168
154
  name: jeweler
169
155
  requirement: !ruby/object:Gem::Requirement
170
156
  requirements:
171
- - - ! '>='
157
+ - - ">="
172
158
  - !ruby/object:Gem::Version
173
159
  version: '0'
174
160
  type: :development
175
161
  prerelease: false
176
162
  version_requirements: !ruby/object:Gem::Requirement
177
163
  requirements:
178
- - - ! '>='
164
+ - - ">="
179
165
  - !ruby/object:Gem::Version
180
166
  version: '0'
181
167
  - !ruby/object:Gem::Dependency
182
168
  name: gemcutter
183
169
  requirement: !ruby/object:Gem::Requirement
184
170
  requirements:
185
- - - ! '>='
171
+ - - ">="
186
172
  - !ruby/object:Gem::Version
187
173
  version: '0'
188
174
  type: :development
189
175
  prerelease: false
190
176
  version_requirements: !ruby/object:Gem::Requirement
191
177
  requirements:
192
- - - ! '>='
178
+ - - ">="
193
179
  - !ruby/object:Gem::Version
194
180
  version: '0'
195
181
  - !ruby/object:Gem::Dependency
196
182
  name: gem-release
197
183
  requirement: !ruby/object:Gem::Requirement
198
184
  requirements:
199
- - - ! '>='
185
+ - - ">="
200
186
  - !ruby/object:Gem::Version
201
187
  version: '0'
202
188
  type: :development
203
189
  prerelease: false
204
190
  version_requirements: !ruby/object:Gem::Requirement
205
191
  requirements:
206
- - - ! '>='
192
+ - - ">="
207
193
  - !ruby/object:Gem::Version
208
194
  version: '0'
209
195
  - !ruby/object:Gem::Dependency
210
196
  name: rake-version
211
197
  requirement: !ruby/object:Gem::Requirement
212
198
  requirements:
213
- - - ! '>='
199
+ - - ">="
214
200
  - !ruby/object:Gem::Version
215
201
  version: '0'
216
202
  type: :development
217
203
  prerelease: false
218
204
  version_requirements: !ruby/object:Gem::Requirement
219
205
  requirements:
220
- - - ! '>='
206
+ - - ">="
221
207
  - !ruby/object:Gem::Version
222
208
  version: '0'
223
209
  - !ruby/object:Gem::Dependency
224
210
  name: simplecov
225
211
  requirement: !ruby/object:Gem::Requirement
226
212
  requirements:
227
- - - ! '>='
213
+ - - ">="
228
214
  - !ruby/object:Gem::Version
229
215
  version: '0'
230
216
  type: :development
231
217
  prerelease: false
232
218
  version_requirements: !ruby/object:Gem::Requirement
233
219
  requirements:
234
- - - ! '>='
220
+ - - ">="
235
221
  - !ruby/object:Gem::Version
236
222
  version: '0'
237
223
  - !ruby/object:Gem::Dependency
238
224
  name: fakefs
239
225
  requirement: !ruby/object:Gem::Requirement
240
226
  requirements:
241
- - - ! '>='
227
+ - - ">="
228
+ - !ruby/object:Gem::Version
229
+ version: '0'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
237
+ - !ruby/object:Gem::Dependency
238
+ name: coveralls
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - ">="
242
242
  - !ruby/object:Gem::Version
243
243
  version: '0'
244
244
  type: :development
245
245
  prerelease: false
246
246
  version_requirements: !ruby/object:Gem::Requirement
247
247
  requirements:
248
- - - ! '>='
248
+ - - ">="
249
249
  - !ruby/object:Gem::Version
250
250
  version: '0'
251
251
  description: Boxafe encrypts and auto-mounts a folder with encfs and whenever.
@@ -267,13 +267,8 @@ files:
267
267
  - lib/boxafe/cli.rb
268
268
  - lib/boxafe/config.rb
269
269
  - lib/boxafe/encfs.rb
270
- - lib/boxafe/notifier.rb
271
- - lib/boxafe/notifier/growl.rb
272
- - lib/boxafe/notifier/notification_center.rb
273
270
  - lib/boxafe/program.rb
274
- - lib/boxafe/scheduler.rb
275
- - lib/boxafe/scheduler/cron.rb
276
- - lib/boxafe/scheduler/launchd.rb
271
+ - lib/boxafe/validator.rb
277
272
  homepage: http://github.com/AlphaHydrae/boxafe
278
273
  licenses:
279
274
  - MIT
@@ -284,17 +279,17 @@ require_paths:
284
279
  - lib
285
280
  required_ruby_version: !ruby/object:Gem::Requirement
286
281
  requirements:
287
- - - ! '>='
282
+ - - ">="
288
283
  - !ruby/object:Gem::Version
289
284
  version: '0'
290
285
  required_rubygems_version: !ruby/object:Gem::Requirement
291
286
  requirements:
292
- - - ! '>='
287
+ - - ">="
293
288
  - !ruby/object:Gem::Version
294
289
  version: '0'
295
290
  requirements: []
296
291
  rubyforge_project:
297
- rubygems_version: 2.1.5
292
+ rubygems_version: 2.4.2
298
293
  signing_key:
299
294
  specification_version: 4
300
295
  summary: Secure your Dropbox with encfs.
@@ -1,27 +0,0 @@
1
- # encoding: UTF-8
2
- require 'growl'
3
-
4
- class Boxafe::Notifier::Growl < Boxafe::Notifier
5
- METHODS = {
6
- info: :notify_info,
7
- success: :notify_ok,
8
- failure: :notify_error
9
- }
10
-
11
- def self.available?
12
- ::Growl.installed?
13
- end
14
-
15
- def notify msg, options = {}
16
- method = METHODS[options.delete(:type)] || :notify_info
17
- ::Growl.send method, msg, growl_options(options)
18
- end
19
-
20
- private
21
-
22
- def growl_options options = {}
23
- @options.dup.tap do |h|
24
- h[:title] = options[:title] if options[:title]
25
- end
26
- end
27
- end
@@ -1,27 +0,0 @@
1
- # encoding: UTF-8
2
- require 'terminal-notifier-guard'
3
-
4
- class Boxafe::Notifier::NotificationCenter < Boxafe::Notifier
5
- METHODS = {
6
- info: :notify,
7
- success: :success,
8
- failure: :failed
9
- }
10
-
11
- def self.available?
12
- TerminalNotifier::Guard.available?
13
- end
14
-
15
- def notify msg, options = {}
16
- method = METHODS[options.delete(:type)] || :notify
17
- TerminalNotifier::Guard.send method, msg, terminal_notifier_options(options)
18
- end
19
-
20
- private
21
-
22
- def terminal_notifier_options options = {}
23
- @options.dup.tap do |h|
24
- h[:title] = options[:title] if options[:title]
25
- end
26
- end
27
- end
@@ -1,43 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- class Boxafe::Notifier
4
- IMPLEMENTATIONS = %w(growl notification_center)
5
-
6
- def self.notifier options = {}
7
- if options[:notify] == true
8
- platform_notifier options
9
- elsif IMPLEMENTATIONS.include?(name = options[:notify].to_s)
10
- notifier_instance name, options
11
- elsif options.key?(:notify) and options[:notify] != false
12
- raise Boxafe::Error, "Unknown notification type #{options[:notify].inspect}"
13
- end
14
- end
15
-
16
- def self.notifier_instance name, options = {}
17
- impl = Boxafe::Notifier.const_get(name.gsub(/(?:\A|_)(.)/){ $1.upcase })
18
- impl.available? ? impl.new(options) : nil
19
- end
20
-
21
- def self.platform_notifier options = {}
22
-
23
- candidates = case RbConfig::CONFIG['host_os']
24
- when /darwin/i
25
- %w(notification_center growl)
26
- else
27
- []
28
- end
29
-
30
- candidates.each do |name|
31
- notifier = notifier_instance name, options
32
- return notifier if notifier
33
- end
34
-
35
- nil
36
- end
37
-
38
- def initialize options = {}
39
- @options = { title: 'Boxafe' }.merge options
40
- end
41
- end
42
-
43
- Dir[File.join File.dirname(__FILE__), File.basename(__FILE__, '.*'), '*.rb'].each{ |lib| require lib }
@@ -1,25 +0,0 @@
1
- # encoding: UTF-8
2
- #require 'whenever'
3
-
4
- class Boxafe::Scheduler::Cron < Boxafe::Scheduler
5
-
6
- def start
7
- raise 'Not yet implemented on this operating system'
8
- Whenever::CommandLine.execute block: mount_schedule, write: true, identifier: 'boxafe-mount'
9
- end
10
-
11
- def stop
12
- raise 'Not yet implemented on this operating system'
13
- Whenever::CommandLine.execute block: mount_schedule, clear: true, identifier: 'boxafe-mount'
14
- end
15
-
16
- private
17
-
18
- def self.mount_schedule
19
- Proc.new do
20
- every 1.minute do
21
- command 'echo $(date) > /Users/unknow/Projects/boxafe/bar.txt'
22
- end
23
- end
24
- end
25
- end
@@ -1,39 +0,0 @@
1
- # encoding: UTF-8
2
- require 'launchdr'
3
- require 'fileutils'
4
-
5
- class Boxafe::Scheduler::Launchd < Boxafe::Scheduler
6
-
7
- def start
8
- stop
9
- plist.dump USER_AGENT
10
- plist.load!
11
- end
12
-
13
- def stop
14
- return false unless plist_exists?
15
- plist.unload!
16
- FileUtils.rm_f plist.file
17
- end
18
-
19
- private
20
-
21
- LABEL = 'com.alphahydrae.boxafe'
22
- USER_AGENT = LaunchDr::Launchd::Paths[:user_agent]
23
-
24
- def plist_exists?
25
- begin
26
- File.exists? plist.file
27
- rescue
28
- false
29
- end
30
- end
31
-
32
- def plist
33
- @plist ||= LaunchDr::Launchd.new(LABEL).tap do |plist|
34
- plist[:ProgramArguments] = [ 'boxafe', 'mount' ]
35
- plist[:RunAtLoad] = true
36
- plist[:EnvironmentVariables] = { 'PATH' => ENV['PATH'] } # TODO: add path option
37
- end
38
- end
39
- end
@@ -1,18 +0,0 @@
1
- # encoding: UTF-8
2
- class Boxafe::Scheduler
3
-
4
- def self.platform_scheduler options = {}
5
- case RbConfig::CONFIG['host_os']
6
- when /darwin/i
7
- Boxafe::Scheduler::Launchd.new options
8
- else
9
- Boxafe::Scheduler::Cron.new options
10
- end
11
- end
12
-
13
- def initialize options = {}
14
- @options = options
15
- end
16
- end
17
-
18
- Dir[File.join File.dirname(__FILE__), File.basename(__FILE__, '.*'), '*.rb'].each{ |lib| require lib }