imapcli 1.0.5 → 2.0.0

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/Guardfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # A sample Guardfile
2
4
  # More info at https://github.com/guard/guard#readme
3
5
 
@@ -15,7 +17,7 @@
15
17
  #
16
18
  # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17
19
 
18
- # Note: The cmd option is now required due to the increasing number of ways
20
+ # NOTE: The cmd option is now required due to the increasing number of ways
19
21
  # rspec may be run, below are examples of the most common uses.
20
22
  # * bundler: 'bundle exec rspec'
21
23
  # * bundler binstubs: 'bin/rspec'
@@ -24,8 +26,8 @@
24
26
  # * zeus: 'zeus rspec' (requires the server to be started separately)
25
27
  # * 'just' rspec: 'rspec'
26
28
 
27
- guard :rspec, cmd: "bundle exec rspec" do
28
- require "guard/rspec/dsl"
29
+ guard :rspec, cmd: 'bundle exec rspec' do
30
+ require 'guard/rspec/dsl'
29
31
  dsl = Guard::RSpec::Dsl.new(self)
30
32
 
31
33
  # Feel free to open issues for suggestions and improvements
@@ -41,7 +43,7 @@ guard :rspec, cmd: "bundle exec rspec" do
41
43
  dsl.watch_spec_files_for(ruby.lib_files)
42
44
 
43
45
  # Rails files
44
- rails = dsl.rails(view_extensions: %w(erb haml slim))
46
+ rails = dsl.rails(view_extensions: %w[erb haml slim])
45
47
  dsl.watch_spec_files_for(rails.app_files)
46
48
  dsl.watch_spec_files_for(rails.views)
47
49
 
@@ -49,7 +51,7 @@ guard :rspec, cmd: "bundle exec rspec" do
49
51
  [
50
52
  rspec.spec.call("routing/#{m[1]}_routing"),
51
53
  rspec.spec.call("controllers/#{m[1]}_controller"),
52
- rspec.spec.call("acceptance/#{m[1]}")
54
+ rspec.spec.call("acceptance/#{m[1]}"),
53
55
  ]
54
56
  end
55
57
 
@@ -60,6 +62,6 @@ guard :rspec, cmd: "bundle exec rspec" do
60
62
  # Turnip features and steps
61
63
  watch(%r{^spec/acceptance/(.+)\.feature$})
62
64
  watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
63
- Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
65
+ Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance'
64
66
  end
65
67
  end
data/README.md CHANGED
@@ -1,8 +1,4 @@
1
- **Heads up! Code contributions welcome. Please issue pull requests against the
2
- `develop` branch.**
3
-
4
- imapcli
5
- =======
1
+ # imapcli
6
2
 
7
3
  > Command-line interface (CLI) for IMAP servers
8
4
  > (<https://github.com/bovender/imapcli>)
@@ -11,23 +7,19 @@ imapcli
11
7
  server for configuration details and e-mail statistics. It can be used to gather
12
8
  IMAP mailbox sizes.
13
9
 
10
+ ## Table of contents
14
11
 
15
- Table of contents
16
- -----------------
17
-
18
- * [Motivation](#motivation)
19
- * [Warning](#warning)
20
- * [Installing and executing `imapcli`](#installing-and-executing-imapcli)
21
- * [Terminology](#terminology)
22
- * [Usage](#usage)
23
- * [Alternative resources](#alternative-resources)
24
- * [State of the project](#state-of-the-project)
25
- * [Credits](#credits)
26
- * [License](#license)
12
+ - [Motivation](#motivation)
13
+ - [Warning](#warning)
14
+ - [Installing and executing `imapcli`](#installing-and-executing-imapcli)
15
+ - [Terminology](#terminology)
16
+ - [Usage](#usage)
17
+ - [Alternative resources](#alternative-resources)
18
+ - [State of the project](#state-of-the-project)
19
+ - [Credits](#credits)
20
+ - [License](#license)
27
21
 
28
-
29
- Motivation
30
- ----------
22
+ ## Motivation
31
23
 
32
24
  When my university mail account had almost reached the quota, I needed to find
33
25
  out what the largest mail folders were (in terms of megabytes, not message
@@ -39,9 +31,7 @@ with the server by telnet or OpenSSL.
39
31
 
40
32
  `imapcli` offers a convenient way to query an IMAP server.
41
33
 
42
-
43
- Warning
44
- -------
34
+ ## Warning
45
35
 
46
36
  Some servers are configured to detect potentially malicious login attempts by
47
37
  the frequency of repeat connections from a given source. **It may happen that
@@ -71,13 +61,7 @@ Do not forget to reload the `jail2ban` configuration afterwards:
71
61
 
72
62
  Of course this only works if your IP addresses do not change too much.
73
63
 
74
- (On Ubuntu Linux, the [indicator-ip](https://github.com/bovender/indicator-ip)
75
- applet may be useful to know your remote IP. Disclaimer: I am the author of this
76
- tool.)
77
-
78
-
79
- Installing and executing `imapcli`
80
- --------------------------------
64
+ ## Installing and executing `imapcli`
81
65
 
82
66
  `imapcli` is a Ruby project and as such does not need to be compiled. To run it
83
67
  on your machine, you can either pull the repository, install a Gem, or use a
@@ -86,8 +70,7 @@ Docker image.
86
70
  Detailed usage instructions follow [below](#usage).
87
71
 
88
72
  I don't currently provide a .deb package because Debian packaging done right
89
- is kind of complicated.
90
-
73
+ is kind of complicated (for me).
91
74
 
92
75
  ### Run in the repository
93
76
 
@@ -100,8 +83,7 @@ Install:
100
83
  Run:
101
84
 
102
85
  cd imapcli
103
- bundle exec bin/imapcli
104
-
86
+ bundle exec exe/imapcli
105
87
 
106
88
  ### Install the gem
107
89
 
@@ -115,7 +97,6 @@ Run:
115
97
 
116
98
  imapcli
117
99
 
118
-
119
100
  ### Docker image
120
101
 
121
102
  With [Docker](https://www.docker.com), you do not have to install Ruby and the
@@ -125,36 +106,31 @@ smaller).
125
106
 
126
107
  Run:
127
108
 
128
- docker run bvndr/imapcli <arguments>
109
+ docker run -it --rm bovender/imapcli <arguments>
129
110
 
130
111
  Example:
131
112
 
132
- docker run bvndr/imapcli -s myserver.example.com -u user -P info
133
-
134
- The Docker repository is at <https://hub.docker.com/r/bvndr/imapcli>.
113
+ docker run -it --rm bovender/imapcli -s myserver.example.com -u user -P info
135
114
 
115
+ The Docker repository is at <https://hub.docker.com/r/bovender/imapcli>.
136
116
 
137
- Terminology
138
- -----------
117
+ ## Terminology
139
118
 
140
119
  `imapcli` attempts to use the typical IMAP terminology. I guess most people
141
120
  have their mails organized in **folders**; in IMAP speak, a folder is a **maibox**.
142
121
 
143
-
144
- Usage
145
- -----
122
+ ## Usage
146
123
 
147
124
  For basic usage instructions and possible options, run `imapcli` and examine
148
125
  the output. Please note that `imapcli` distinguishes between global and
149
126
  command-specific options. Global options *precede* and command-specific options
150
- *follow* a `command`, see the output of `imapcli` (without command or options)
127
+ -follow* a `command`, see the output of `imapcli` (without command or options)
151
128
  for more information.
152
129
 
153
130
  Note: The following examples use the command `imapcli`. Depending on how you
154
131
  [installed](#installing-and-executing-imapcli) `imapcli`, you may need to use a
155
132
  different command.
156
133
 
157
-
158
134
  ### Setting your server and account information
159
135
 
160
136
  Server and account information are given as *global options*:
@@ -179,7 +155,6 @@ environment variables:
179
155
  These variables can also be set in a `.env` file that resides in the root
180
156
  directory of the repository. Never add this `.env` file to the repository!
181
157
 
182
-
183
158
  ### Obtain general information about the IMAP server
184
159
 
185
160
  $ bundle exec bin/imapcli -s yourserver.example.com -u myusername -P info
@@ -191,7 +166,6 @@ directory of the repository. Never add this `.env` file to the repository!
191
166
  hierarchy separator: /
192
167
  quota: IMAP QUOTA extension not supported by this server
193
168
 
194
-
195
169
  ### List all mailboxes (folders) without size information
196
170
 
197
171
  $ bundle exec bin/imapcli -s yourserver.example.com -u myusername -P list
@@ -205,7 +179,6 @@ directory of the repository. Never add this `.env` file to the repository!
205
179
  - Sports
206
180
  ...
207
181
 
208
-
209
182
  ### Obtain size information about mailboxes
210
183
 
211
184
  To obtain mailbox sizes, the server has to be queried for the message sizes for
@@ -214,14 +187,15 @@ of messages in them, this may take a little while.
214
187
 
215
188
  `imapcli` prints the following statistics about the message sizes in a mailbox:
216
189
 
217
- * `Count`: Number of individual messages
218
- * `Total size`: Total size of all messages in the mailbox (in kiB)
219
- * `Min`: Size of the smallest message in the mailbox (in kiB)
220
- * `Q1`: First quartile of message sizes in the mailbox (in kiB)
221
- * `Median`: Median of all message sizes in the mailbox (in kiB)
222
- * `Q3`: First quartile of message sizes in the mailbox (in kiB)
223
- * `Max`: Size of the largest message in the mailbox (in kiB)
190
+ - `Count`: Number of individual messages
191
+ - `Total size`: Total size of all messages in the mailbox
192
+ - `Min`: Size of the smallest message in the mailbox
193
+ - `Q1`: First quartile of message sizes in the mailbox
194
+ - `Median`: Median of all message sizes in the mailbox
195
+ - `Q3`: Third quartile of message sizes in the mailbox
196
+ - `Max`: Size of the largest message in the mailbox
224
197
 
198
+ Use the `-H` or `--human` switch to output the message sizes with SI prefixes.
225
199
 
226
200
  #### All mailboxes
227
201
 
@@ -273,88 +247,81 @@ Use the `-r`/`--recurse` flag:
273
247
  By default, mailboxes are sorted alphabetically. To sort by a specific statistic,
274
248
  use an `-o`/`--sort` option:
275
249
 
276
- * `-o count`
277
- * `-o total_size`
278
- * `-o min_size`
279
- * `-o q1`
280
- * `-o median_size`
281
- * `-o q3`
282
- * `-o max_size`
250
+ - `-o count`
251
+ - `-o total_size`
252
+ - `-o min_size`
253
+ - `-o q1_size`
254
+ - `-o median_size`
255
+ - `-o q3_size`
256
+ - `-o max_size`
257
+
258
+ This will sort the output from smallest to largest (ascending).
259
+
260
+ Use the `--reverse` switch to sort from largest to smallest (descending).
261
+
262
+ Note that these are options to the `stats` command and need to come after the `stats`
263
+ keyword, as shown below.
283
264
 
284
265
  Example:
285
266
 
286
- $ bundle exec bin/imapcli -s yourserver.example.com -u myusername -P stats -r -o max_size Archive
267
+ bundle exec -it bin/imapcli -s yourserver.example.com -u myusername -P stats -r -o max_size Archive
287
268
 
288
269
  #### Obtaining comma-separated values (CSV)
289
270
 
290
271
  Use the `--csv` flag.
291
272
 
292
-
293
- Alternative resources
294
- ---------------------
273
+ ## Alternative resources
295
274
 
296
275
  While researching command-line tools for IMAP servers, I came across the
297
276
  following:
298
277
 
299
-
300
278
  ### IMAP folder size script
301
279
 
302
- * <https://code.iamcal.com/pl/imap_folders>
303
-
304
- Ad-hoc perl script that computes the sizes of each mailbox. `imapcli` was
305
- inspired by this!
280
+ - <https://code.iamcal.com/pl/imap_folders>
306
281
 
282
+ Ad-hoc perl script that computes the sizes of each mailbox. `imapcli` was
283
+ inspired by this!
307
284
 
308
285
  ### IMAP synchronization and backup tools
309
286
 
310
- * <https://github.com/OfflineIMAP/imapfw>
311
-
312
- Framework to work with mails
287
+ - <https://github.com/OfflineIMAP/imapfw>
313
288
 
314
- * <https://github.com/polo2ro/imapbox>
289
+ Framework to work with mails
315
290
 
316
- Pull down e-mails from an IMAP server to your local disk
291
+ - <https://github.com/polo2ro/imapbox>
317
292
 
293
+ Pull down e-mails from an IMAP server to your local disk
318
294
 
295
+ ## State of the project
319
296
 
320
- ### IMAP via Telnet or OpenSSL
321
-
322
-
323
- State of the project
324
- --------------------
325
-
326
- While `imapcli` does what I need it to do, there are a lot of things that could
327
- be improved. I'll be happy to take **pull request**. Please issue those against
328
- the **develop** branch as I like to follow *[a successful Git branching
329
- model](http://nvie.com/git-model)*.
330
-
331
-
332
- ### Versioning
297
+ I have not been able to work on this project for quite some time. It still
298
+ serves me well when I occasionally need it. Pull requests are of course welcome.
333
299
 
334
300
  This project is [semantically versioned](https://semver.org).
335
301
 
336
302
  ### To do
337
303
 
338
- - More human-friendly number formatting (e.g., MiB/GiB as appropriate)
339
- - Output to file
340
- - Deal with server-specific mailbox separator characters (e.g. '.' vs. '/')
341
- - Man page
342
- - More commands?
343
-
304
+ [x] More human-friendly number formatting (e.g., MiB/GiB as appropriate)
305
+ [ ] Output to file
306
+ [ ] Deal with server-specific mailbox separator characters (e.g. '.' vs. '/')
307
+ [ ] Man page
308
+ [ ] More commands?
344
309
 
345
- Credits
346
- -------
310
+ ## Credits
347
311
 
348
312
  This tool is build around the awesome [GLI](https://github.com/davetron5000/gli)
349
313
  gem by [David Copeland](https://github.com/davetron5000) and makes extensive use
350
314
  of [Piotr Murach's](https://github.com/piotrmurach) excellent `TTY` tools. See
351
315
  the `Gemfile` for other work that this tool depends on.
352
316
 
317
+ ## Contributors
318
+
319
+ - [@bovender](https://github.com/bovender)
320
+ - [@n-rodriguez](https://github.com/n-rodriguez)
353
321
 
354
- License
355
- -------
322
+ ## License
356
323
 
357
- &copy; 2017 Daniel Kraus (bovender)
324
+ &copy; 2017-2025 Daniel Kraus (@bovender)
358
325
 
359
326
  Licensed under the Apache License, Version 2.0 (the "License");
360
327
  you may not use this file except in compliance with the License.
data/Rakefile CHANGED
@@ -1,20 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rake/clean'
2
4
  require 'rubygems'
3
5
  require 'rubygems/package_task'
4
6
  require 'rdoc/task'
5
7
  # require 'cucumber'
6
8
  # require 'cucumber/rake/task'
9
+
7
10
  Rake::RDocTask.new do |rd|
8
- rd.main = "README.md"
9
- rd.rdoc_files.include("README.md","lib/**/*.rb","bin/**/*")
11
+ rd.main = 'README.md'
12
+ rd.rdoc_files.include('README.md', 'lib/**/*.rb', 'bin/**/*')
10
13
  rd.title = 'imapcli'
11
14
  end
12
15
 
13
- spec = eval(File.read('imapcli.gemspec'))
14
-
15
- Gem::PackageTask.new(spec) do |pkg|
16
- end
17
-
18
16
  # CUKE_RESULTS = 'results.html'
19
17
  # CLEAN << CUKE_RESULTS
20
18
  # desc 'Run features'
data/bin/bundle ADDED
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'bundle' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "rubygems"
12
+
13
+ m = Module.new do
14
+ module_function
15
+
16
+ def invoked_as_script?
17
+ File.expand_path($0) == File.expand_path(__FILE__)
18
+ end
19
+
20
+ def env_var_version
21
+ ENV["BUNDLER_VERSION"]
22
+ end
23
+
24
+ def cli_arg_version
25
+ return unless invoked_as_script? # don't want to hijack other binstubs
26
+ return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
27
+ bundler_version = nil
28
+ update_index = nil
29
+ ARGV.each_with_index do |a, i|
30
+ if update_index && update_index.succ == i && a.match?(Gem::Version::ANCHORED_VERSION_PATTERN)
31
+ bundler_version = a
32
+ end
33
+ next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
34
+ bundler_version = $1
35
+ update_index = i
36
+ end
37
+ bundler_version
38
+ end
39
+
40
+ def gemfile
41
+ gemfile = ENV["BUNDLE_GEMFILE"]
42
+ return gemfile if gemfile && !gemfile.empty?
43
+
44
+ File.expand_path("../Gemfile", __dir__)
45
+ end
46
+
47
+ def lockfile
48
+ lockfile =
49
+ case File.basename(gemfile)
50
+ when "gems.rb" then gemfile.sub(/\.rb$/, ".locked")
51
+ else "#{gemfile}.lock"
52
+ end
53
+ File.expand_path(lockfile)
54
+ end
55
+
56
+ def lockfile_version
57
+ return unless File.file?(lockfile)
58
+ lockfile_contents = File.read(lockfile)
59
+ return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
60
+ Regexp.last_match(1)
61
+ end
62
+
63
+ def bundler_requirement
64
+ @bundler_requirement ||=
65
+ env_var_version ||
66
+ cli_arg_version ||
67
+ bundler_requirement_for(lockfile_version)
68
+ end
69
+
70
+ def bundler_requirement_for(version)
71
+ return "#{Gem::Requirement.default}.a" unless version
72
+
73
+ bundler_gem_version = Gem::Version.new(version)
74
+
75
+ bundler_gem_version.approximate_recommendation
76
+ end
77
+
78
+ def load_bundler!
79
+ ENV["BUNDLE_GEMFILE"] ||= gemfile
80
+
81
+ activate_bundler
82
+ end
83
+
84
+ def activate_bundler
85
+ gem_error = activation_error_handling do
86
+ gem "bundler", bundler_requirement
87
+ end
88
+ return if gem_error.nil?
89
+ require_error = activation_error_handling do
90
+ require "bundler/version"
91
+ end
92
+ return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
93
+ warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
94
+ exit 42
95
+ end
96
+
97
+ def activation_error_handling
98
+ yield
99
+ nil
100
+ rescue StandardError, LoadError => e
101
+ e
102
+ end
103
+ end
104
+
105
+ m.load_bundler!
106
+
107
+ if m.invoked_as_script?
108
+ load Gem.bin_path("bundler", "bundle")
109
+ end
data/bin/rspec ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rspec' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12
+
13
+ bundle_binstub = File.expand_path("bundle", __dir__)
14
+
15
+ if File.file?(bundle_binstub)
16
+ if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
17
+ load(bundle_binstub)
18
+ else
19
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
20
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
21
+ end
22
+ end
23
+
24
+ require "rubygems"
25
+ require "bundler/setup"
26
+
27
+ load Gem.bin_path("rspec-core", "rspec")
data/bin/rubocop ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rubocop' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
12
+
13
+ bundle_binstub = File.expand_path('bundle', __dir__)
14
+
15
+ if File.file?(bundle_binstub)
16
+ if File.read(bundle_binstub, 300).include?('This file was generated by Bundler')
17
+ load(bundle_binstub)
18
+ else
19
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
20
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
21
+ end
22
+ end
23
+
24
+ require 'rubygems'
25
+ require 'bundler/setup'
26
+
27
+ load Gem.bin_path('rubocop', 'rubocop')
data/exe/imapcli ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../lib/imapcli'
5
+
6
+ Dotenv.load
7
+
8
+ exit Imapcli::Cli.run(ARGV)
data/imapcli.gemspec CHANGED
@@ -1,28 +1,35 @@
1
- # Ensure we require the local version and not one we might have installed already
2
- require File.join([File.dirname(__FILE__),'lib','imapcli','version.rb'])
3
- spec = Gem::Specification.new do |s|
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/imapcli/version'
4
+
5
+ Gem::Specification.new do |s|
4
6
  s.name = 'imapcli'
5
7
  s.version = Imapcli::VERSION
8
+ s.platform = Gem::Platform::RUBY
6
9
  s.author = 'Daniel Kraus (bovender)'
7
10
  s.email = 'bovender@bovender.de'
8
11
  s.homepage = 'https://github.com/bovender/imapcli'
9
- s.license = 'Apache-2.0'
10
- s.platform = Gem::Platform::RUBY
11
12
  s.summary = 'Command-line tool to query IMAP servers'
13
+ s.license = 'Apache-2.0'
14
+
15
+ s.required_ruby_version = '>= 3.1.0'
16
+
12
17
  s.files = `git ls-files`.split("\n")
13
- s.require_paths << 'lib'
14
- s.has_rdoc = true
15
- s.extra_rdoc_files = ['README.md','imapcli.rdoc']
18
+
19
+ s.extra_rdoc_files = ['README.md', 'imapcli.rdoc']
16
20
  s.rdoc_options << '--title' << 'imapcli' << '--main' << 'README.md' << '-ri'
17
- s.bindir = 'bin'
18
- s.executables << 'imapcli'
19
- s.add_development_dependency('rake', '~> 12.3.3')
20
- s.add_development_dependency('rdoc', '~> 5.1')
21
- s.add_runtime_dependency('descriptive_statistics', '~> 2.5')
22
- s.add_runtime_dependency('dotenv', '~> 2.2')
23
- s.add_runtime_dependency('filesize', '~> 0.1')
24
- s.add_runtime_dependency('gli','~> 2.17')
25
- s.add_runtime_dependency('tty-progressbar', '~> 0.13')
26
- s.add_runtime_dependency('tty-prompt', '~> 0.13')
27
- s.add_runtime_dependency('tty-table', '~> 0.9')
21
+
22
+ s.bindir = 'exe'
23
+ s.executables = ['imapcli']
24
+
25
+ s.add_dependency('csv')
26
+ s.add_dependency('descriptive_statistics', '~> 2.5')
27
+ s.add_dependency('dotenv', '~> 3.1')
28
+ s.add_dependency('activesupport', '~> 8.0')
29
+ s.add_dependency('gli', '~> 2.22')
30
+ s.add_dependency('net-imap')
31
+ s.add_dependency('tty-progressbar', '~> 0.18')
32
+ s.add_dependency('tty-prompt', '~> 0.23')
33
+ s.add_dependency('tty-table', '~> 0.12')
34
+ s.add_dependency('zeitwerk', '~> 2.7.0')
28
35
  end