imap-backup 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +2 -1
  5. data/.travis.yml +1 -1
  6. data/README.md +12 -0
  7. data/bin/imap-backup +11 -6
  8. data/docker-compose.yml +15 -0
  9. data/imap-backup.gemspec +3 -2
  10. data/lib/email/mboxrd/message.rb +30 -4
  11. data/lib/email/provider.rb +2 -2
  12. data/lib/imap/backup.rb +0 -1
  13. data/lib/imap/backup/account/connection.rb +29 -15
  14. data/lib/imap/backup/account/folder.rb +3 -3
  15. data/lib/imap/backup/configuration/account.rb +15 -12
  16. data/lib/imap/backup/configuration/asker.rb +3 -1
  17. data/lib/imap/backup/configuration/folder_chooser.rb +5 -2
  18. data/lib/imap/backup/configuration/list.rb +12 -9
  19. data/lib/imap/backup/configuration/setup.rb +5 -3
  20. data/lib/imap/backup/configuration/store.rb +4 -4
  21. data/lib/imap/backup/downloader.rb +6 -2
  22. data/lib/imap/backup/serializer/base.rb +2 -2
  23. data/lib/imap/backup/serializer/mbox.rb +16 -7
  24. data/lib/imap/backup/utils.rb +8 -3
  25. data/lib/imap/backup/version.rb +1 -1
  26. data/spec/features/backup_spec.rb +27 -0
  27. data/spec/features/helper.rb +2 -0
  28. data/spec/features/support/backup_directory.rb +27 -0
  29. data/spec/features/support/email_server.rb +40 -0
  30. data/spec/features/support/shared/connection_context.rb +12 -0
  31. data/spec/features/support/shared/message_fixtures.rb +6 -0
  32. data/spec/fixtures/connection.yml +7 -0
  33. data/spec/support/fixtures.rb +6 -0
  34. data/spec/unit/account/connection_spec.rb +19 -7
  35. data/spec/unit/account/folder_spec.rb +15 -5
  36. data/spec/unit/configuration/account_spec.rb +18 -8
  37. data/spec/unit/configuration/asker_spec.rb +6 -3
  38. data/spec/unit/configuration/connection_tester_spec.rb +1 -1
  39. data/spec/unit/configuration/folder_chooser_spec.rb +21 -11
  40. data/spec/unit/configuration/list_spec.rb +13 -6
  41. data/spec/unit/configuration/setup_spec.rb +5 -3
  42. data/spec/unit/configuration/store_spec.rb +13 -8
  43. data/spec/unit/downloader_spec.rb +3 -1
  44. data/spec/unit/email/mboxrd/message_spec.rb +32 -13
  45. data/spec/unit/email/provider_spec.rb +7 -3
  46. data/spec/unit/serializer/base_spec.rb +3 -2
  47. data/spec/unit/serializer/mbox_spec.rb +9 -6
  48. data/spec/unit/utils_spec.rb +15 -13
  49. metadata +35 -5
  50. data/lib/imap/backup/serializer/directory.rb +0 -43
  51. data/spec/unit/serializer/directory_spec.rb +0 -69
@@ -1,7 +1,7 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Imap::Backup::Serializer::Mbox do
4
- let(:stat) { double("File::Stat", mode: 0700) }
4
+ let(:stat) { double("File::Stat", mode: 0o700) }
5
5
  let(:base_path) { "/base/path" }
6
6
  let(:mbox_pathname) { "/base/path/my/folder.mbox" }
7
7
  let(:mbox_exists) { true }
@@ -20,7 +20,8 @@ describe Imap::Backup::Serializer::Mbox do
20
20
  it "creates the containing directory" do
21
21
  described_class.new(base_path, "my/folder")
22
22
 
23
- expect(Imap::Backup::Utils).to have_received(:make_folder).with(base_path, "my", 0700)
23
+ expect(Imap::Backup::Utils).
24
+ to have_received(:make_folder).with(base_path, "my", 0o700)
24
25
  end
25
26
 
26
27
  context "mbox and imap files" do
@@ -73,14 +74,16 @@ describe Imap::Backup::Serializer::Mbox do
73
74
  context "#save" do
74
75
  let(:mbox_formatted_message) { "message in mbox format" }
75
76
  let(:message_uid) { "999" }
76
- let(:message) { double("Email::Mboxrd::Message", to_s: mbox_formatted_message) }
77
+ let(:message) do
78
+ double("Email::Mboxrd::Message", to_serialized: mbox_formatted_message)
79
+ end
77
80
  let(:mbox_file) { double("File - mbox", write: nil, close: nil) }
78
81
  let(:imap_file) { double("File - imap", write: nil, close: nil) }
79
82
 
80
83
  before do
81
84
  allow(Email::Mboxrd::Message).to receive(:new).and_return(message)
82
- allow(File).to receive(:open).with(mbox_pathname, "ab").and_return(mbox_file)
83
- allow(File).to receive(:open).with(imap_pathname, "ab").and_return(imap_file)
85
+ allow(File).to receive(:open).with(mbox_pathname, "ab") { mbox_file }
86
+ allow(File).to receive(:open).with(imap_pathname, "ab") { imap_file }
84
87
  end
85
88
 
86
89
  it "saves the message to the mbox" do
@@ -97,7 +100,7 @@ describe Imap::Backup::Serializer::Mbox do
97
100
 
98
101
  context "when the message causes parsing errors" do
99
102
  before do
100
- allow(message).to receive(:to_s).and_raise(ArgumentError)
103
+ allow(message).to receive(:to_serialized).and_raise(ArgumentError)
101
104
  end
102
105
 
103
106
  it "skips the message" do
@@ -3,7 +3,7 @@ require "spec_helper"
3
3
  describe Imap::Backup::Utils do
4
4
  let(:filename) { "foobar" }
5
5
  let(:stat) { double("File::Stat", mode: mode) }
6
- let(:mode) { 0777 }
6
+ let(:mode) { 0o777 }
7
7
  let(:exists) { true }
8
8
 
9
9
  before do
@@ -12,13 +12,13 @@ describe Imap::Backup::Utils do
12
12
  end
13
13
 
14
14
  context ".check_permissions" do
15
- let(:requested) { 0345 }
15
+ let(:requested) { 0o345 }
16
16
 
17
17
  context "with existing files" do
18
18
  [
19
- [0100, "less than the limit", true],
20
- [0345, "equal to the limit", true],
21
- [0777, "over the limit", false]
19
+ [0o100, "less than the limit", true],
20
+ [0o345, "equal to the limit", true],
21
+ [0o777, "over the limit", false]
22
22
  ].each do |mode, description, success|
23
23
  context "when permissions are #{description}" do
24
24
  let(:mode) { mode }
@@ -29,9 +29,10 @@ describe Imap::Backup::Utils do
29
29
  end
30
30
  else
31
31
  it "fails" do
32
+ message = /Permissions on '.*?' should be .*?, not .*?/
32
33
  expect do
33
34
  described_class.check_permissions(filename, requested)
34
- end.to raise_error(RuntimeError, format("Permissions on '%s' should be 0%o, not 0%o", filename, requested, mode))
35
+ end.to raise_error(RuntimeError, message)
35
36
  end
36
37
  end
37
38
  end
@@ -40,7 +41,7 @@ describe Imap::Backup::Utils do
40
41
 
41
42
  context "with non-existent files" do
42
43
  let(:exists) { false }
43
- let(:mode) { 0111 }
44
+ let(:mode) { 0o111 }
44
45
 
45
46
  it "succeeds" do
46
47
  described_class.check_permissions(filename, requested)
@@ -50,10 +51,10 @@ describe Imap::Backup::Utils do
50
51
 
51
52
  context ".stat" do
52
53
  context "with existing files" do
53
- let(:mode) { 02345 }
54
+ let(:mode) { 0o2345 }
54
55
 
55
56
  it "is the last 9 bits of the file mode" do
56
- expect(described_class.stat(filename)).to eq(0345)
57
+ expect(described_class.stat(filename)).to eq(0o345)
57
58
  end
58
59
  end
59
60
 
@@ -73,21 +74,22 @@ describe Imap::Backup::Utils do
73
74
  end
74
75
 
75
76
  it "does nothing if an empty path is supplied" do
76
- described_class.make_folder("aaa", "", 0222)
77
+ described_class.make_folder("aaa", "", 0o222)
77
78
 
78
79
  expect(FileUtils).to_not have_received(:mkdir_p)
79
80
  end
80
81
 
81
82
  it "creates the path" do
82
- described_class.make_folder("/base/path", "new/folder", 0222)
83
+ described_class.make_folder("/base/path", "new/folder", 0o222)
83
84
 
84
85
  expect(FileUtils).to have_received(:mkdir_p).with("/base/path/new/folder")
85
86
  end
86
87
 
87
88
  it "sets permissions on the path" do
88
- described_class.make_folder("/base/path/new", "folder", 0222)
89
+ described_class.make_folder("/base/path/new", "folder", 0o222)
89
90
 
90
- expect(FileUtils).to have_received(:chmod).with(0222, "/base/path/new/folder")
91
+ expect(FileUtils).
92
+ to have_received(:chmod).with(0o222, "/base/path/new/folder")
91
93
  end
92
94
  end
93
95
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imap-backup
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe Yates
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-14 00:00:00.000000000 Z
11
+ date: 2019-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: 0.4.8
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-byebug
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rspec
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -117,6 +131,7 @@ extensions: []
117
131
  extra_rdoc_files: []
118
132
  files:
119
133
  - ".gitignore"
134
+ - ".rspec"
120
135
  - ".rubocop.yml"
121
136
  - ".travis.yml"
122
137
  - Gemfile
@@ -124,6 +139,7 @@ files:
124
139
  - README.md
125
140
  - Rakefile
126
141
  - bin/imap-backup
142
+ - docker-compose.yml
127
143
  - imap-backup.gemspec
128
144
  - lib/email/mboxrd/message.rb
129
145
  - lib/email/provider.rb
@@ -139,12 +155,19 @@ files:
139
155
  - lib/imap/backup/configuration/store.rb
140
156
  - lib/imap/backup/downloader.rb
141
157
  - lib/imap/backup/serializer/base.rb
142
- - lib/imap/backup/serializer/directory.rb
143
158
  - lib/imap/backup/serializer/mbox.rb
144
159
  - lib/imap/backup/utils.rb
145
160
  - lib/imap/backup/version.rb
161
+ - spec/features/backup_spec.rb
162
+ - spec/features/helper.rb
163
+ - spec/features/support/backup_directory.rb
164
+ - spec/features/support/email_server.rb
165
+ - spec/features/support/shared/connection_context.rb
166
+ - spec/features/support/shared/message_fixtures.rb
167
+ - spec/fixtures/connection.yml
146
168
  - spec/gather_rspec_coverage.rb
147
169
  - spec/spec_helper.rb
170
+ - spec/support/fixtures.rb
148
171
  - spec/support/higline_test_helpers.rb
149
172
  - spec/support/shared_examples/account_flagging.rb
150
173
  - spec/support/silence_logging.rb
@@ -161,9 +184,9 @@ files:
161
184
  - spec/unit/email/mboxrd/message_spec.rb
162
185
  - spec/unit/email/provider_spec.rb
163
186
  - spec/unit/serializer/base_spec.rb
164
- - spec/unit/serializer/directory_spec.rb
165
187
  - spec/unit/serializer/mbox_spec.rb
166
188
  - spec/unit/utils_spec.rb
189
+ - tmp/.gitkeep
167
190
  homepage: https://github.com/joeyates/imap-backup
168
191
  licenses: []
169
192
  metadata: {}
@@ -188,8 +211,16 @@ signing_key:
188
211
  specification_version: 4
189
212
  summary: Backup GMail (or other IMAP) accounts to disk
190
213
  test_files:
214
+ - spec/features/backup_spec.rb
215
+ - spec/features/helper.rb
216
+ - spec/features/support/backup_directory.rb
217
+ - spec/features/support/email_server.rb
218
+ - spec/features/support/shared/connection_context.rb
219
+ - spec/features/support/shared/message_fixtures.rb
220
+ - spec/fixtures/connection.yml
191
221
  - spec/gather_rspec_coverage.rb
192
222
  - spec/spec_helper.rb
223
+ - spec/support/fixtures.rb
193
224
  - spec/support/higline_test_helpers.rb
194
225
  - spec/support/shared_examples/account_flagging.rb
195
226
  - spec/support/silence_logging.rb
@@ -206,6 +237,5 @@ test_files:
206
237
  - spec/unit/email/mboxrd/message_spec.rb
207
238
  - spec/unit/email/provider_spec.rb
208
239
  - spec/unit/serializer/base_spec.rb
209
- - spec/unit/serializer/directory_spec.rb
210
240
  - spec/unit/serializer/mbox_spec.rb
211
241
  - spec/unit/utils_spec.rb
@@ -1,43 +0,0 @@
1
- require "fileutils"
2
-
3
- module Imap::Backup
4
- module Serializer; end
5
-
6
- class Serializer::Directory < Serializer::Base
7
- def initialize(path, folder)
8
- super
9
- Utils.make_folder(@path, @folder, Serializer::DIRECTORY_PERMISSIONS)
10
- end
11
-
12
- def uids
13
- return [] if !File.exist?(directory)
14
-
15
- d = Dir.open(directory)
16
- as_strings = d.map do |file|
17
- file[/^0*(\d+).json$/, 1]
18
- end.compact
19
- as_strings.map(&:to_i).sort
20
- end
21
-
22
- def exist?(uid)
23
- message_filename = filename(uid)
24
- File.exist?(message_filename)
25
- end
26
-
27
- def save(uid, message)
28
- message_filename = filename(uid)
29
- File.open(message_filename, "w") { |f| f.write message.to_json }
30
- FileUtils.chmod 0600, message_filename
31
- end
32
-
33
- private
34
-
35
- def directory
36
- File.join(@path, @folder)
37
- end
38
-
39
- def filename(uid)
40
- "#{directory}/%012u.json" % uid.to_i
41
- end
42
- end
43
- end
@@ -1,69 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Imap::Backup::Serializer::Directory do
4
- let(:stat) { double("File::Stat", mode: 0700) }
5
- let(:files) { ["00000123.json", "000001.json"] }
6
- let(:base) { "/base/path" }
7
- let(:folder) { "/base/path/my_folder" }
8
- let(:folder_exists) { true }
9
-
10
- before do
11
- allow(FileUtils).to receive(:mkdir_p)
12
- allow(FileUtils).to receive(:chmod)
13
- allow(File).to receive(:stat).with(base).and_return(stat)
14
- allow(File).to receive(:exist?).with(base).and_return(true)
15
- allow(File).to receive(:exist?).with(folder).and_return(folder_exists)
16
- end
17
-
18
- subject { described_class.new(base, "my_folder") }
19
-
20
- context "#uids" do
21
- before do
22
- allow(Dir).to receive(:open).with(folder).and_return(files)
23
- end
24
-
25
- it "returns the backed-up uids" do
26
- expect(subject.uids).to eq([1, 123])
27
- end
28
-
29
- context "if the directory does not exist" do
30
- let(:folder_exists) { false }
31
-
32
- it "returns an empty array" do
33
- expect(subject.uids).to eq([])
34
- end
35
- end
36
- end
37
-
38
- context "#exist?" do
39
- it "checks if the file exists" do
40
- allow(File).to receive(:exist?).with(%r{/base/path/my_folder/0+123.json}).and_return(true)
41
-
42
- expect(subject.exist?(123)).to be_truthy
43
- end
44
- end
45
-
46
- context "#save" do
47
- let(:message) { {"RFC822" => "the body", "other" => "xxx"} }
48
- let(:file) { double("File", write: nil) }
49
-
50
- before do
51
- allow(File).to receive(:exist?).with(%r{/base/path/my_folder/0+1234.json}).and_return(true)
52
- allow(File).to receive(:open) do |&block|
53
- block.call file
54
- end
55
- end
56
-
57
- it "saves messages" do
58
- subject.save("1234", message)
59
-
60
- expect(file).to have_received(:write).with(message.to_json)
61
- end
62
-
63
- it "sets file permissions" do
64
- subject.save(1234, message)
65
-
66
- expect(FileUtils).to have_received(:chmod).with(0600, /0+1234.json$/)
67
- end
68
- end
69
- end