duplicati 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # Duplicati
2
+ [![Gem Version](https://badge.fury.io/rb/duplicati.png)](http://badge.fury.io/rb/duplicati)
2
3
  [![Build Status](https://secure.travis-ci.org/jarmo/duplicati-rb.png)](http://travis-ci.org/jarmo/duplicati-rb)
3
4
  [![Coverage](https://coveralls.io/repos/jarmo/duplicati-rb/badge.png?branch=master)](https://coveralls.io/r/jarmo/duplicati-rb)
4
5
 
@@ -136,6 +137,25 @@ class CustomNotification
136
137
  end
137
138
  ````
138
139
 
140
+ ## Execution status
141
+
142
+ Duplicati has a ````#execution_success?```` method for determining the success
143
+ status of backup command:
144
+
145
+ ````ruby
146
+ Duplicati.backup(options).execution_success? # => "true" when execution was a success.
147
+ ````
148
+
149
+ ## Fine Grained Commands Execution
150
+
151
+ It is possible to execute commands separately when needed:
152
+
153
+ ````ruby
154
+ Duplicati.backup(options).execution_success?
155
+ # is same as
156
+ Duplicati.new(options).backup.clean.notify.execution_success?
157
+ ````
158
+
139
159
  ## Limitations
140
160
 
141
161
  * Currently only backup is supported. Use Duplicati's command line or GUI utility directly for restoring.
@@ -21,10 +21,6 @@ class Duplicati
21
21
  --usn-policy=auto
22
22
  --snapshot-policy=auto
23
23
  --full-if-sourcefolder-changed
24
- 2>&1 1>> "#{@log_path}" &&
25
-
26
- "#{@duplicati_path}" delete-all-but-n 5 "#{@backup_store_path}"
27
- --force
28
24
  2>&1 1>> "#{@log_path}"]
29
25
  end
30
26
 
@@ -0,0 +1,16 @@
1
+ class Duplicati
2
+ class Clean
3
+ def initialize(opts)
4
+ @duplicati_path = opts[:duplicati_path]
5
+ @backup_store_path = opts[:backup_store_path] or raise ":backup_store_path option is missing for clean!"
6
+ @log_path = opts[:log_path]
7
+ end
8
+
9
+ def command
10
+ %Q["#{@duplicati_path}" delete-all-but-n 5 "#{@backup_store_path}"
11
+ --force
12
+ 2>&1 1>> "#{@log_path}"]
13
+ end
14
+
15
+ end
16
+ end
@@ -1,3 +1,3 @@
1
1
  class Duplicati
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
data/lib/duplicati.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require File.expand_path("duplicati/version", File.dirname(__FILE__))
2
2
  require File.expand_path("duplicati/backup", File.dirname(__FILE__))
3
+ require File.expand_path("duplicati/clean", File.dirname(__FILE__))
3
4
  require File.expand_path("duplicati/notification/base", File.dirname(__FILE__))
4
5
  require File.expand_path("duplicati/notification/growl", File.dirname(__FILE__))
5
6
  require File.expand_path("duplicati/notification/mail", File.dirname(__FILE__))
@@ -8,7 +9,7 @@ class Duplicati
8
9
 
9
10
  class << self
10
11
  def backup(opts={})
11
- new(opts).backup
12
+ new(opts).backup.clean.notify
12
13
  end
13
14
  end
14
15
 
@@ -26,6 +27,7 @@ class Duplicati
26
27
  end
27
28
 
28
29
  @opts = opts
30
+ @execution_success = true
29
31
  end
30
32
 
31
33
  def backup
@@ -33,6 +35,24 @@ class Duplicati
33
35
  options :duplicati_path, :backup_paths, :backup_store_path,
34
36
  :backup_encryption_key, :inclusion_filters, :exclusion_filters, :log_path
35
37
  ).command
38
+
39
+ self
40
+ end
41
+
42
+ def clean
43
+ execute Clean.new(
44
+ options :duplicati_path, :backup_store_path, :log_path
45
+ ).command
46
+
47
+ self
48
+ end
49
+
50
+ def notify
51
+ @opts[:notifications].each do |notification|
52
+ notification.notify execution_success?
53
+ end
54
+
55
+ self
36
56
  end
37
57
 
38
58
  private
@@ -47,8 +67,6 @@ class Duplicati
47
67
  puts formatted_command if $DEBUG
48
68
  system(formatted_command)
49
69
  @exit_status = $?.exitstatus
50
- notify
51
- execution_success?
52
70
  end
53
71
 
54
72
  def options(*options_to_extract)
@@ -62,12 +80,6 @@ class Duplicati
62
80
  command.gsub($/, "").squeeze(" ")
63
81
  end
64
82
 
65
- def notify
66
- @opts[:notifications].each do |notification|
67
- notification.notify execution_success?
68
- end
69
- end
70
-
71
83
  # https://code.google.com/p/duplicati/issues/detail?id=678
72
84
  # 0 - Success
73
85
  # 1 - Success (but no changed files)
@@ -76,7 +88,7 @@ class Duplicati
76
88
  # 100 - No connection to server -> Fatal error
77
89
  # 200 - Invalid command/arguments
78
90
  def execution_success?
79
- @exit_status && @exit_status.between?(0, 2)
91
+ @execution_success &&= @exit_status && @exit_status.between?(0, 2)
80
92
  end
81
93
 
82
94
  end
@@ -40,10 +40,6 @@ describe Duplicati::Backup do
40
40
  --usn-policy=auto
41
41
  --snapshot-policy=auto
42
42
  --full-if-sourcefolder-changed
43
- 2>&1 1>> "/zzz/output.log" &&
44
-
45
- "/bin/duplicati-commandline" delete-all-but-n 5 "file:///foo/backup"
46
- --force
47
43
  2>&1 1>> "/zzz/output.log"]
48
44
  end
49
45
 
@@ -0,0 +1,26 @@
1
+ require "spec_helper"
2
+
3
+ describe Duplicati::Clean do
4
+
5
+ context "#initialize" do
6
+ it "raises an Exception if backup store path is not provided" do
7
+ expect {
8
+ Duplicati::Clean.new(:backup_paths => [])
9
+ }.to raise_error(RuntimeError, ":backup_store_path option is missing for clean!")
10
+ end
11
+ end
12
+
13
+ context "#command" do
14
+
15
+ it "generates clean command for Duplicati using different options" do
16
+ Duplicati::Clean.new(
17
+ :duplicati_path => "/bin/duplicati-commandline",
18
+ :backup_store_path => "file:///foo/backup",
19
+ :log_path => "/zzz/output.log"
20
+ ).command.should == %Q["/bin/duplicati-commandline" delete-all-but-n 5 "file:///foo/backup"
21
+ --force
22
+ 2>&1 1>> "/zzz/output.log"]
23
+ end
24
+
25
+ end
26
+ end
@@ -73,12 +73,12 @@ describe Duplicati do
73
73
  end
74
74
 
75
75
  context "#backup" do
76
- it "executes the backup command" do
76
+ it "executes the backup command and returns self" do
77
77
  Duplicati::Backup.any_instance.should_receive(:command).and_return("backup command")
78
78
  duplicati = Duplicati.new(:backup_paths => [], :backup_store_path => "")
79
79
  duplicati.should_receive(:execute).with("backup command")
80
80
 
81
- duplicati.backup
81
+ duplicati.backup.should == duplicati
82
82
  end
83
83
 
84
84
  it "proxies options to backup command" do
@@ -102,11 +102,14 @@ describe Duplicati do
102
102
  end
103
103
 
104
104
  context ".backup" do
105
- it "is a convenience method for .new#backup" do
105
+ it "is a convenience method for .new#backup#clean#notify" do
106
106
  Duplicati::Backup.any_instance.should_receive(:command).and_return("backup command")
107
107
  Duplicati.any_instance.should_receive(:execute).with("backup command")
108
+ Duplicati::Clean.any_instance.should_receive(:command).and_return("clean command")
109
+ Duplicati.any_instance.should_receive(:execute).with("clean command")
110
+ Duplicati.any_instance.should_receive(:notify)
108
111
 
109
- Duplicati.backup(:backup_paths => [], :backup_store_path => "")
112
+ Duplicati.backup(:backup_paths => [], :backup_store_path => "", :notifications => [])
110
113
  end
111
114
  end
112
115
 
@@ -130,7 +133,7 @@ describe Duplicati do
130
133
  $?.should_receive(:exitstatus).and_return -1
131
134
 
132
135
  duplicati = Duplicati.new
133
- duplicati.send(:execute, "").should be_false
136
+ duplicati.send(:execute, "")
134
137
  duplicati.should_not be_execution_success
135
138
  end
136
139
 
@@ -139,7 +142,20 @@ describe Duplicati do
139
142
  $?.should_receive(:exitstatus).and_return 3
140
143
 
141
144
  duplicati = Duplicati.new
142
- duplicati.send(:execute, "").should be_false
145
+ duplicati.send(:execute, "")
146
+ duplicati.should_not be_execution_success
147
+ end
148
+
149
+ it "is false when one of the commands fail with invalid exit status" do
150
+ duplicati = Duplicati.new
151
+
152
+ Object.any_instance.should_receive(:system).twice.and_return true
153
+ $?.should_receive(:exitstatus).and_return 0
154
+ duplicati.send(:execute, "")
155
+ duplicati.should be_execution_success
156
+
157
+ $?.should_receive(:exitstatus).and_return 3
158
+ duplicati.send(:execute, "")
143
159
  duplicati.should_not be_execution_success
144
160
  end
145
161
 
@@ -148,7 +164,7 @@ describe Duplicati do
148
164
  $?.should_receive(:exitstatus).and_return 0
149
165
 
150
166
  duplicati = Duplicati.new
151
- duplicati.send(:execute, "").should be_true
167
+ duplicati.send(:execute, "")
152
168
  duplicati.should be_execution_success
153
169
  end
154
170
 
@@ -157,7 +173,7 @@ describe Duplicati do
157
173
  $?.should_receive(:exitstatus).and_return 1
158
174
 
159
175
  duplicati = Duplicati.new
160
- duplicati.send(:execute, "").should be_true
176
+ duplicati.send(:execute, "")
161
177
  duplicati.should be_execution_success
162
178
  end
163
179
 
@@ -166,7 +182,19 @@ describe Duplicati do
166
182
  $?.should_receive(:exitstatus).and_return 2
167
183
 
168
184
  duplicati = Duplicati.new
169
- duplicati.send(:execute, "").should be_true
185
+ duplicati.send(:execute, "")
186
+ duplicati.should be_execution_success
187
+ end
188
+
189
+ it "is true when all of the commands succeed with success exit status" do
190
+ duplicati = Duplicati.new
191
+
192
+ Object.any_instance.should_receive(:system).twice.and_return true
193
+ $?.should_receive(:exitstatus).twice.and_return 0
194
+ duplicati.send(:execute, "")
195
+ duplicati.should be_execution_success
196
+
197
+ duplicati.send(:execute, "")
170
198
  duplicati.should be_execution_success
171
199
  end
172
200
  end
@@ -176,26 +204,31 @@ describe Duplicati do
176
204
  Duplicati.any_instance.unstub(:notify)
177
205
  end
178
206
 
207
+ it "returns self" do
208
+ duplicati = Duplicati.new
209
+ duplicati.notify.should == duplicati
210
+ end
211
+
179
212
  it "notifies with all possible notifications with false execution success" do
180
- Object.any_instance.stub(:system).and_return false
181
- $?.should_receive(:exitstatus).and_return 3
182
213
  notification1 = double('notification1').as_null_object
183
214
  notification2 = double('notification2').as_null_object
184
-
185
215
  notification1.should_receive(:notify).with(false)
186
216
  notification2.should_receive(:notify).with(false)
187
- Duplicati.new(:notifications => [notification1, notification2]).send(:execute, "")
217
+
218
+ duplicati = Duplicati.new(:notifications => [notification1, notification2])
219
+ duplicati.should_receive(:execution_success?).twice.and_return(false)
220
+ duplicati.notify
188
221
  end
189
222
 
190
223
  it "notifies with all possible notifications with true execution success" do
191
- Object.any_instance.stub(:system).and_return true
192
- $?.should_receive(:exitstatus).and_return 0
193
224
  notification1 = double('notification1').as_null_object
194
225
  notification2 = double('notification2').as_null_object
195
-
196
226
  notification1.should_receive(:notify).with(true)
197
227
  notification2.should_receive(:notify).with(true)
198
- Duplicati.new(:notifications => [notification1, notification2]).send(:execute, "")
228
+
229
+ duplicati = Duplicati.new(:notifications => [notification1, notification2])
230
+ duplicati.should_receive(:execution_success?).twice.and_return(true)
231
+ duplicati.notify
199
232
  end
200
233
  end
201
234
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: duplicati
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-02 00:00:00.000000000 Z
12
+ date: 2013-02-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -61,6 +61,7 @@ files:
61
61
  - duplicati.gemspec
62
62
  - lib/duplicati.rb
63
63
  - lib/duplicati/backup.rb
64
+ - lib/duplicati/clean.rb
64
65
  - lib/duplicati/notification/base.rb
65
66
  - lib/duplicati/notification/failed.png
66
67
  - lib/duplicati/notification/growl.rb
@@ -68,6 +69,7 @@ files:
68
69
  - lib/duplicati/notification/success.png
69
70
  - lib/duplicati/version.rb
70
71
  - spec/duplicati/backup_spec.rb
72
+ - spec/duplicati/clean_spec.rb
71
73
  - spec/duplicati/notification/growl_spec.rb
72
74
  - spec/duplicati/notification/mail_spec.rb
73
75
  - spec/duplicati_spec.rb
@@ -86,7 +88,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
86
88
  version: '0'
87
89
  segments:
88
90
  - 0
89
- hash: -480531571
91
+ hash: -685447987
90
92
  required_rubygems_version: !ruby/object:Gem::Requirement
91
93
  none: false
92
94
  requirements:
@@ -95,7 +97,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
97
  version: '0'
96
98
  segments:
97
99
  - 0
98
- hash: -480531571
100
+ hash: -685447987
99
101
  requirements: []
100
102
  rubyforge_project:
101
103
  rubygems_version: 1.8.24
@@ -105,6 +107,7 @@ summary: Duplicati backup utility wrapper in Ruby with easier API and sensible c
105
107
  defaults.
106
108
  test_files:
107
109
  - spec/duplicati/backup_spec.rb
110
+ - spec/duplicati/clean_spec.rb
108
111
  - spec/duplicati/notification/growl_spec.rb
109
112
  - spec/duplicati/notification/mail_spec.rb
110
113
  - spec/duplicati_spec.rb