duplicati 0.0.7 → 0.0.8

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.
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