imap-backup 14.6.1 → 15.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/imap-backup.gemspec +1 -1
- data/lib/imap/backup/account/folder_backup.rb +12 -15
- data/lib/imap/backup/account/folder_mapper.rb +2 -2
- data/lib/imap/backup/cli/helpers.rb +4 -62
- data/lib/imap/backup/cli/options.rb +74 -0
- data/lib/imap/backup/client/automatic_login_wrapper.rb +3 -3
- data/lib/imap/backup/flag_refresher.rb +7 -0
- data/lib/imap/backup/logger.rb +2 -2
- data/lib/imap/backup/naming.rb +1 -1
- data/lib/imap/backup/retry_on_error.rb +2 -2
- data/lib/imap/backup/serializer/delayed_metadata_serializer.rb +33 -5
- data/lib/imap/backup/serializer/imap.rb +23 -3
- data/lib/imap/backup/serializer/message_enumerator.rb +2 -2
- data/lib/imap/backup/serializer.rb +2 -13
- data/lib/imap/backup/setup/asker.rb +1 -1
- data/lib/imap/backup/version.rb +3 -3
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: de4f5bfc1260430435d380fd3fa6c315efad4ef503b0429bce041615d3ae2e10
|
4
|
+
data.tar.gz: 3c1541e30cb01d1ecd6da9372e79b8e8c71f119eee5a11770bef76b90e89e037
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25aa565a7860560958b59c5f88f67b470128405acc15fc67fe3683152d0ea9c63d8787287f006249a22b26a88d92425bed653254126ef92259ea85022b33efcb
|
7
|
+
data.tar.gz: 54d8df69cef34dcafd3ba97f63f202b0f00e2306f8e12c4ea7329dfae5028e42e9a4050630fae2d03131048aa3c70e90ee7bb8a49a1388084bd136ad3e0ce973
|
data/imap-backup.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |gem|
|
|
18
18
|
|
19
19
|
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
20
20
|
gem.require_paths = ["lib"]
|
21
|
-
gem.required_ruby_version = ">=
|
21
|
+
gem.required_ruby_version = ">= 3.0"
|
22
22
|
|
23
23
|
gem.add_runtime_dependency "highline"
|
24
24
|
gem.add_runtime_dependency "mail", "2.7.1"
|
@@ -29,11 +29,13 @@ module Imap::Backup
|
|
29
29
|
|
30
30
|
serializer.apply_uid_validity(folder.uid_validity)
|
31
31
|
|
32
|
-
|
32
|
+
serializer.transaction do
|
33
33
|
downloader.run
|
34
|
+
FlagRefresher.new(folder, serializer).run if account.mirror_mode || refresh
|
34
35
|
end
|
35
|
-
|
36
|
-
|
36
|
+
# After the transaction the serializer will have any appended messages
|
37
|
+
# so we can check differences between the server and the local backup
|
38
|
+
LocalOnlyMessageDeleter.new(folder, raw_serializer).run if account.mirror_mode
|
37
39
|
end
|
38
40
|
|
39
41
|
private
|
@@ -55,34 +57,29 @@ module Imap::Backup
|
|
55
57
|
true
|
56
58
|
end
|
57
59
|
|
58
|
-
def clean_up
|
59
|
-
LocalOnlyMessageDeleter.new(folder, serializer).run if account.mirror_mode
|
60
|
-
FlagRefresher.new(folder, serializer).run if account.mirror_mode || refresh
|
61
|
-
end
|
62
|
-
|
63
60
|
def downloader
|
64
61
|
@downloader ||= Downloader.new(
|
65
62
|
folder,
|
66
|
-
|
63
|
+
serializer,
|
67
64
|
multi_fetch_size: account.multi_fetch_size,
|
68
65
|
reset_seen_flags_after_fetch: account.reset_seen_flags_after_fetch
|
69
66
|
)
|
70
67
|
end
|
71
68
|
|
72
|
-
def
|
73
|
-
@
|
69
|
+
def serializer
|
70
|
+
@serializer ||=
|
74
71
|
case account.download_strategy
|
75
72
|
when "direct"
|
76
|
-
|
73
|
+
raw_serializer
|
77
74
|
when "delay_metadata"
|
78
|
-
Serializer::DelayedMetadataSerializer.new(serializer:
|
75
|
+
Serializer::DelayedMetadataSerializer.new(serializer: raw_serializer)
|
79
76
|
else
|
80
77
|
raise "Unknown download strategy '#{account.download_strategy}'"
|
81
78
|
end
|
82
79
|
end
|
83
80
|
|
84
|
-
def
|
85
|
-
@
|
81
|
+
def raw_serializer
|
82
|
+
@raw_serializer ||= Serializer.new(account.local_path, folder.name)
|
86
83
|
end
|
87
84
|
end
|
88
85
|
end
|
@@ -32,7 +32,7 @@ module Imap::Backup
|
|
32
32
|
# @yieldparam serializer [Serializer] the folder's serializer
|
33
33
|
# @yieldparam folder [Account::Folder] the online folder
|
34
34
|
# @return [Enumerator, void]
|
35
|
-
def each
|
35
|
+
def each(&block)
|
36
36
|
return enum_for(:each) if !block_given?
|
37
37
|
|
38
38
|
glob = File.join(source_local_path, "**", "*.imap")
|
@@ -40,7 +40,7 @@ module Imap::Backup
|
|
40
40
|
name = source_folder_name(path)
|
41
41
|
serializer = Serializer.new(source_local_path, name)
|
42
42
|
folder = destination_folder_for_path(name)
|
43
|
-
|
43
|
+
block.call(serializer, folder)
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require "thor"
|
2
2
|
|
3
|
+
require "imap/backup/cli/options"
|
3
4
|
require "imap/backup/configuration"
|
4
5
|
require "imap/backup/configuration_not_found"
|
5
6
|
|
@@ -11,67 +12,8 @@ module Imap::Backup
|
|
11
12
|
# Provides helper methods for CLI classes
|
12
13
|
module CLI::Helpers
|
13
14
|
def self.included(base)
|
14
|
-
base
|
15
|
-
|
16
|
-
method_option(
|
17
|
-
"accounts",
|
18
|
-
type: :string,
|
19
|
-
desc: "a comma-separated list of accounts (defaults to all configured accounts)",
|
20
|
-
aliases: ["-a"]
|
21
|
-
)
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.config_option
|
25
|
-
method_option(
|
26
|
-
"config",
|
27
|
-
type: :string,
|
28
|
-
desc: "supply the configuration file path (default: ~/.imap-backup/config.json)",
|
29
|
-
aliases: ["-c"]
|
30
|
-
)
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.format_option
|
34
|
-
method_option(
|
35
|
-
"format",
|
36
|
-
type: :string,
|
37
|
-
desc: "the output type, 'text' for plain text or 'json'",
|
38
|
-
aliases: ["-f"]
|
39
|
-
)
|
40
|
-
end
|
41
|
-
|
42
|
-
def self.quiet_option
|
43
|
-
method_option(
|
44
|
-
"quiet",
|
45
|
-
type: :boolean,
|
46
|
-
desc: "silence all output",
|
47
|
-
aliases: ["-q"]
|
48
|
-
)
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.refresh_option
|
52
|
-
method_option(
|
53
|
-
"refresh",
|
54
|
-
type: :boolean,
|
55
|
-
desc: "in the default 'keep all emails' mode, " \
|
56
|
-
"updates flags for messages that are already downloaded",
|
57
|
-
aliases: ["-r"]
|
58
|
-
)
|
59
|
-
end
|
60
|
-
|
61
|
-
def self.verbose_option
|
62
|
-
method_option(
|
63
|
-
"verbose",
|
64
|
-
type: :boolean,
|
65
|
-
desc:
|
66
|
-
"increase the amount of logging. " \
|
67
|
-
"Without this option, the program gives minimal output. " \
|
68
|
-
"Using this option once gives more detailed output. " \
|
69
|
-
"Whereas, using this option twice also shows all IMAP network calls",
|
70
|
-
aliases: ["-v"],
|
71
|
-
repeatable: true
|
72
|
-
)
|
73
|
-
end
|
74
|
-
end
|
15
|
+
options = CLI::Options.new(base: base)
|
16
|
+
options.define_options
|
75
17
|
end
|
76
18
|
|
77
19
|
# Processes command-line parameters
|
@@ -81,7 +23,7 @@ module Imap::Backup
|
|
81
23
|
def options
|
82
24
|
@symbolized_options ||= # rubocop:disable Naming/MemoizedInstanceVariableName
|
83
25
|
begin
|
84
|
-
options = super
|
26
|
+
options = super
|
85
27
|
options.each.with_object({}) do |(k, v), acc|
|
86
28
|
key =
|
87
29
|
if k.is_a?(String)
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require "thor"
|
2
|
+
|
3
|
+
module Imap; end
|
4
|
+
|
5
|
+
module Imap::Backup
|
6
|
+
class CLI < Thor; end
|
7
|
+
|
8
|
+
# Defines option methods for CLI classes
|
9
|
+
class CLI::Options
|
10
|
+
attr_reader :base
|
11
|
+
|
12
|
+
# Options common to many commands
|
13
|
+
OPTIONS = [
|
14
|
+
{
|
15
|
+
name: "accounts",
|
16
|
+
parameters: {
|
17
|
+
type: :string, aliases: ["-a"],
|
18
|
+
desc: "a comma-separated list of accounts (defaults to all configured accounts)"
|
19
|
+
}
|
20
|
+
},
|
21
|
+
{
|
22
|
+
name: "config",
|
23
|
+
parameters: {
|
24
|
+
type: :string, aliases: ["-c"],
|
25
|
+
desc: "supply the configuration file path (default: ~/.imap-backup/config.json)"
|
26
|
+
}
|
27
|
+
},
|
28
|
+
{
|
29
|
+
name: "format",
|
30
|
+
parameters: {
|
31
|
+
type: :string, desc: "the output type, 'text' for plain text or 'json'", aliases: ["-f"]
|
32
|
+
}
|
33
|
+
},
|
34
|
+
{
|
35
|
+
name: "quiet",
|
36
|
+
parameters: {
|
37
|
+
type: :boolean, desc: "silence all output", aliases: ["-q"]
|
38
|
+
}
|
39
|
+
},
|
40
|
+
{
|
41
|
+
name: "refresh",
|
42
|
+
parameters: {
|
43
|
+
type: :boolean, aliases: ["-r"],
|
44
|
+
desc: "in the default 'keep all emails' mode, " \
|
45
|
+
"updates flags for messages that are already downloaded"
|
46
|
+
}
|
47
|
+
},
|
48
|
+
{
|
49
|
+
name: "verbose",
|
50
|
+
parameters: {
|
51
|
+
type: :boolean, aliases: ["-v"], repeatable: true,
|
52
|
+
desc: "increase the amount of logging. " \
|
53
|
+
"Without this option, the program gives minimal output. " \
|
54
|
+
"Using this option once gives more detailed output. " \
|
55
|
+
"Whereas, using this option twice also shows all IMAP network calls"
|
56
|
+
}
|
57
|
+
}
|
58
|
+
].freeze
|
59
|
+
|
60
|
+
def initialize(base:)
|
61
|
+
@base = base
|
62
|
+
end
|
63
|
+
|
64
|
+
def define_options
|
65
|
+
OPTIONS.each do |option|
|
66
|
+
base.singleton_class.class_eval do
|
67
|
+
define_method("#{option[:name]}_option") do
|
68
|
+
method_option(option[:name], **option[:parameters])
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -23,12 +23,12 @@ module Imap::Backup
|
|
23
23
|
# Proxies calls to the client.
|
24
24
|
# Before the first call does login
|
25
25
|
# @return the return value of the client method called
|
26
|
-
def method_missing(method_name,
|
26
|
+
def method_missing(method_name, ...)
|
27
27
|
if login_called
|
28
|
-
client.send(method_name,
|
28
|
+
client.send(method_name, ...)
|
29
29
|
else
|
30
30
|
do_first_login
|
31
|
-
client.send(method_name,
|
31
|
+
client.send(method_name, ...) if method_name != :login
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -28,6 +28,13 @@ module Imap::Backup
|
|
28
28
|
|
29
29
|
def refresh_block(uids)
|
30
30
|
uids_and_flags = folder.fetch_multi(uids, ["FLAGS"])
|
31
|
+
if !uids_and_flags
|
32
|
+
Logger.logger.debug(
|
33
|
+
"[#{folder.name}] failed to fetch flags for #{uids} - " \
|
34
|
+
"cannot refresh flags"
|
35
|
+
)
|
36
|
+
return
|
37
|
+
end
|
31
38
|
uids_and_flags.each do |uid_and_flags|
|
32
39
|
uid = uid_and_flags[:uid]
|
33
40
|
flags = uid_and_flags[:flags]
|
data/lib/imap/backup/logger.rb
CHANGED
@@ -51,11 +51,11 @@ module Imap::Backup
|
|
51
51
|
# Wraps a block, filtering output to standard error,
|
52
52
|
# hidng passwords and outputs the results to standard out
|
53
53
|
# @return [void]
|
54
|
-
def self.sanitize_stderr
|
54
|
+
def self.sanitize_stderr(&block)
|
55
55
|
sanitizer = Text::Sanitizer.new($stdout)
|
56
56
|
previous_stderr = $stderr
|
57
57
|
$stderr = sanitizer
|
58
|
-
|
58
|
+
block.call
|
59
59
|
ensure
|
60
60
|
sanitizer.flush
|
61
61
|
$stderr = previous_stderr
|
data/lib/imap/backup/naming.rb
CHANGED
@@ -7,7 +7,7 @@ module Imap::Backup
|
|
7
7
|
# The characters that cannot be used in file names
|
8
8
|
INVALID_FILENAME_CHARACTERS = ":%;".freeze
|
9
9
|
# A regular expression that captures each disallowed character
|
10
|
-
INVALID_FILENAME_CHARACTER_MATCH = /([#{INVALID_FILENAME_CHARACTERS}])
|
10
|
+
INVALID_FILENAME_CHARACTER_MATCH = /([#{INVALID_FILENAME_CHARACTERS}])/
|
11
11
|
|
12
12
|
# @param name [String] a folder name
|
13
13
|
# @return [String] the supplied string iwth disallowed characters replaced
|
@@ -13,9 +13,9 @@ module Imap::Backup
|
|
13
13
|
# @param on_error [Proc] a block to call when an error occurs
|
14
14
|
# @raise any error ocurring more than `limit` times
|
15
15
|
# @return the result of any successful completion of the block
|
16
|
-
def retry_on_error(errors:, limit: 10, on_error: nil)
|
16
|
+
def retry_on_error(errors:, limit: 10, on_error: nil, &block)
|
17
17
|
tries ||= 1
|
18
|
-
|
18
|
+
block.call
|
19
19
|
rescue *errors => e
|
20
20
|
if tries < limit
|
21
21
|
message = "#{e}, attempt #{tries} of #{limit}"
|
@@ -10,7 +10,7 @@ module Imap; end
|
|
10
10
|
module Imap::Backup
|
11
11
|
class Serializer; end
|
12
12
|
|
13
|
-
# Wraps the Serializer, delaying metadata
|
13
|
+
# Wraps the Serializer, delaying metadata changes
|
14
14
|
class Serializer::DelayedMetadataSerializer
|
15
15
|
extend Forwardable
|
16
16
|
|
@@ -31,7 +31,7 @@ module Imap::Backup
|
|
31
31
|
def transaction(&block)
|
32
32
|
tsx.fail_in_transaction!(:transaction, message: "nested transactions are not supported")
|
33
33
|
|
34
|
-
tsx.begin({
|
34
|
+
tsx.begin({appends: [], updates: []}) do
|
35
35
|
mbox.transaction do
|
36
36
|
block.call
|
37
37
|
|
@@ -42,7 +42,21 @@ module Imap::Backup
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
#
|
45
|
+
# Sets the folder's UID validity via the serializer
|
46
|
+
#
|
47
|
+
# @param uid_validity [Integer] the UID validity to apply
|
48
|
+
# @raise [RuntimeError] if called inside a transaction
|
49
|
+
# @return [void]
|
50
|
+
def apply_uid_validity(uid_validity)
|
51
|
+
tsx.fail_in_transaction!(
|
52
|
+
:transaction,
|
53
|
+
message: "UID validity cannot be changed in a transaction"
|
54
|
+
)
|
55
|
+
|
56
|
+
serializer.apply_uid_validity(uid_validity)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Appends a message to the mbox file and adds the appended message's metadata
|
46
60
|
# to the transaction
|
47
61
|
#
|
48
62
|
# @param uid [Integer] the UID of the message
|
@@ -53,10 +67,21 @@ module Imap::Backup
|
|
53
67
|
tsx.fail_outside_transaction!(:append)
|
54
68
|
mboxrd_message = Email::Mboxrd::Message.new(message)
|
55
69
|
serialized = mboxrd_message.to_serialized
|
56
|
-
tsx.data[:
|
70
|
+
tsx.data[:appends] << {uid: uid, length: serialized.bytesize, flags: flags}
|
57
71
|
mbox.append(serialized)
|
58
72
|
end
|
59
73
|
|
74
|
+
# Stores changes to a message's metadata for later update
|
75
|
+
#
|
76
|
+
# @param uid [Integer] the UID of the message
|
77
|
+
# @param length [Integer] the length of the message
|
78
|
+
# @param flags [Array<Symbol>] the flags for the message
|
79
|
+
# @return [void]
|
80
|
+
def update(uid, length: nil, flags: nil)
|
81
|
+
tsx.fail_outside_transaction!(:update)
|
82
|
+
tsx.data[:updates] << {uid: uid, length: length, flags: flags}
|
83
|
+
end
|
84
|
+
|
60
85
|
private
|
61
86
|
|
62
87
|
attr_reader :serializer
|
@@ -64,9 +89,12 @@ module Imap::Backup
|
|
64
89
|
def commit
|
65
90
|
# rubocop:disable Lint/RescueException
|
66
91
|
imap.transaction do
|
67
|
-
tsx.data[:
|
92
|
+
tsx.data[:appends].each do |m|
|
68
93
|
imap.append m[:uid], m[:length], flags: m[:flags]
|
69
94
|
end
|
95
|
+
tsx.data[:updates].each do |m|
|
96
|
+
imap.update m[:uid], length: m[:length], flags: m[:flags]
|
97
|
+
end
|
70
98
|
rescue Exception => e
|
71
99
|
Logger.logger.error "#{self.class} handling #{e.class}"
|
72
100
|
imap.rollback
|
@@ -97,11 +97,27 @@ module Imap::Backup
|
|
97
97
|
save
|
98
98
|
end
|
99
99
|
|
100
|
-
#
|
100
|
+
# Updates a message's length and/or flags
|
101
|
+
# @param uid [Integer] the existing message's UID
|
102
|
+
# @param length [Integer] the length of the message (as stored on disk)
|
103
|
+
# @param flags [Array[Symbol]] the message's flags
|
104
|
+
# @raise [RuntimeError] if the UID does not exist
|
105
|
+
# @return [void]
|
106
|
+
def update(uid, length: nil, flags: nil)
|
107
|
+
index = messages.find_index { |m| m.uid == uid }
|
108
|
+
raise "UID #{uid} not found" if !index
|
109
|
+
|
110
|
+
messages[index].length = length if length
|
111
|
+
messages[index].flags = flags if flags
|
112
|
+
save
|
113
|
+
end
|
114
|
+
|
115
|
+
# Get a copy of message metadata
|
101
116
|
# @param uid [Integer] a message UID
|
102
117
|
# @return [Serializer::Message]
|
103
118
|
def get(uid)
|
104
|
-
messages.find { |m| m.uid == uid }
|
119
|
+
message = messages.find { |m| m.uid == uid }
|
120
|
+
message&.dup
|
105
121
|
end
|
106
122
|
|
107
123
|
# Deletes the metadata file
|
@@ -158,11 +174,15 @@ module Imap::Backup
|
|
158
174
|
messages.map(&:uid)
|
159
175
|
end
|
160
176
|
|
161
|
-
# Update a message's
|
177
|
+
# Update a message's UID
|
162
178
|
# @param old [Integer] the existing message UID
|
163
179
|
# @param new [Integer] the new UID to apply to the message
|
180
|
+
# @raise [RuntimeError] if the new UID already exists
|
164
181
|
# @return [void]
|
165
182
|
def update_uid(old, new)
|
183
|
+
existing = messages.find_index { |m| m.uid == new }
|
184
|
+
raise "UID #{new} already exists" if existing
|
185
|
+
|
166
186
|
index = messages.find_index { |m| m.uid == old }
|
167
187
|
return if index.nil?
|
168
188
|
|
@@ -14,14 +14,14 @@ module Imap::Backup
|
|
14
14
|
# @param uids [Array<Integer>] the message UIDs of the messages to iterate over
|
15
15
|
# @yieldparam message [Serializer::Message]
|
16
16
|
# @return [void]
|
17
|
-
def run(uids
|
17
|
+
def run(uids:, &block)
|
18
18
|
uids.each do |uid_maybe_string|
|
19
19
|
uid = uid_maybe_string.to_i
|
20
20
|
message = imap.get(uid)
|
21
21
|
|
22
22
|
next if !message
|
23
23
|
|
24
|
-
|
24
|
+
block.call(message)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -28,6 +28,7 @@ module Imap::Backup
|
|
28
28
|
extend Forwardable
|
29
29
|
|
30
30
|
def_delegator :mbox, :pathname, :mbox_pathname
|
31
|
+
def_delegator :imap, :update
|
31
32
|
|
32
33
|
# Get message metadata
|
33
34
|
# @param uid [Integer] a message UID
|
@@ -77,7 +78,7 @@ module Imap::Backup
|
|
77
78
|
@validated = nil
|
78
79
|
end
|
79
80
|
|
80
|
-
# Calls the supplied block.
|
81
|
+
# Calls the supplied block without implementing transactional behaviour.
|
81
82
|
# This method is present so that this class implements the same
|
82
83
|
# interface as {DelayedMetadataSerializer}
|
83
84
|
# @param block [block] the block that is wrapped by the transaction
|
@@ -177,18 +178,6 @@ module Imap::Backup
|
|
177
178
|
appender.append(uid: uid, message: message, flags: flags)
|
178
179
|
end
|
179
180
|
|
180
|
-
# Updates a messages flags
|
181
|
-
# @param uid [Integer] the message's UID
|
182
|
-
# @param flags [Array<Symbol>] the flags to set on the message
|
183
|
-
# @return [void]
|
184
|
-
def update(uid, flags: nil)
|
185
|
-
message = imap.get(uid)
|
186
|
-
return if !message
|
187
|
-
|
188
|
-
message.flags = flags if flags
|
189
|
-
imap.save
|
190
|
-
end
|
191
|
-
|
192
181
|
# Enumerates over a series of messages.
|
193
182
|
# When called without a block, returns an Enumerator
|
194
183
|
# @param required_uids [Array<Integer>] the UIDs of the message to enumerate over
|
data/lib/imap/backup/version.rb
CHANGED
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:
|
4
|
+
version: 15.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joe Yates
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: highline
|
@@ -153,6 +153,7 @@ files:
|
|
153
153
|
- lib/imap/backup/cli/helpers.rb
|
154
154
|
- lib/imap/backup/cli/local.rb
|
155
155
|
- lib/imap/backup/cli/local/check.rb
|
156
|
+
- lib/imap/backup/cli/options.rb
|
156
157
|
- lib/imap/backup/cli/remote.rb
|
157
158
|
- lib/imap/backup/cli/restore.rb
|
158
159
|
- lib/imap/backup/cli/setup.rb
|
@@ -226,7 +227,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
226
227
|
requirements:
|
227
228
|
- - ">="
|
228
229
|
- !ruby/object:Gem::Version
|
229
|
-
version: '
|
230
|
+
version: '3.0'
|
230
231
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
231
232
|
requirements:
|
232
233
|
- - ">="
|