imap_guard 0.0.1 → 0.0.2

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/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format d
3
+ --order random
@@ -0,0 +1,17 @@
1
+ language: ruby
2
+ after_script:
3
+ - cane
4
+ - yard stats --list-undoc
5
+ rvm:
6
+ - 1.9.3
7
+ - 2.0.0
8
+ - ruby-head
9
+ - rbx-19mode
10
+ matrix:
11
+ allow_failures:
12
+ - rvm: ruby-head
13
+ - rvm: rbx-19mode
14
+ notifications:
15
+ email:
16
+ on_success: always
17
+ on_failure: always
@@ -0,0 +1,10 @@
1
+ # More info at https://github.com/guard/guard#readme
2
+
3
+ guard 'rspec' do
4
+ watch(%r{^spec/.+_spec\.rb$})
5
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
6
+ watch(%r{^lib/(.+)/(.+)\.rb$}) { |m| "spec/#{m[1]}/#{m[2]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ watch(%r{^spec/support/.+\.rb$}) { "spec" }
9
+ end
10
+
data/README.md CHANGED
@@ -1,65 +1,94 @@
1
- # ImapGuard
1
+ # ImapGuard [![Build Status](https://secure.travis-ci.org/infertux/imap_guard.png?branch=master)](https://travis-ci.org/infertux/imap_guard) [![Dependency Status](https://gemnasium.com/infertux/imap_guard.png)](https://gemnasium.com/infertux/imap_guard) [![Code Climate](https://codeclimate.com/github/infertux/imap_guard.png)](https://codeclimate.com/github/infertux/imap_guard)
2
2
 
3
- TODO: Write a gem description
3
+ A guard for your IMAP mailboxes.
4
+
5
+ ImapGuard connects to your IMAP server and processes your emails.
6
+ You can finely pick them thanks to advanced search queries and Ruby blocks.
7
+ Then you can `move` or `delete` them in batch.
8
+
9
+ Of course, there is a _dry-run_ mode (i.e. read-only) available to double check what it would do.
10
+
11
+ It can be used by a disposable script to clean things up or with a cron job to keep them tidy.
4
12
 
5
13
  ## Installation
6
14
 
7
- Add this line to your application's Gemfile:
15
+ $ gem install imap_guard
8
16
 
9
- gem 'imap_guard'
17
+ ## Usage
10
18
 
11
- And then execute:
19
+ Example initialization:
12
20
 
13
- $ bundle
21
+ ```ruby
22
+ require 'imap_guard'
14
23
 
15
- Or install it yourself as:
24
+ SETTINGS = {
25
+ host: 'mail.google.com',
26
+ port: 993,
27
+ username: 'login',
28
+ password: 'pass',
29
+ read_only: true # don't perform any modification aka dry-run mode
30
+ }
31
+
32
+ guard = IMAPGuard::Guard.new SETTINGS
33
+ guard.login # authenticate the user
34
+ guard.select 'INBOX.ops' # select the mailbox
35
+ ```
16
36
 
17
- $ gem install imap_guard
37
+ IMAP search query syntax can be a bit tricky.
38
+ `IMAPGuard::Query` can help you to build queries with a simple Ruby DSL:
18
39
 
19
- ## Usage
40
+ ```ruby
41
+ base_query = IMAPGuard::Query.new.unflagged.unanswered.seen.freeze
42
+ query = base_query.dup.before(7).subject("abc").from("root")
43
+ p query #=> ["UNFLAGGED", "UNANSWERED", "SEEN", "BEFORE", "13-Mar-2013", "SUBJECT", "abc", "FROM", "root"]
44
+ guard.delete query # will delete every emails which match this query
45
+ ```
20
46
 
21
- TODO: Write usage instructions here
47
+ Unfortunately, IMAP search queries are limited too.
48
+ For instance, the pattern passed to `subject` and `from` is a mere string.
49
+ IMAP doesn't allow advanced filtering such as regexp matching.
22
50
 
51
+ To do so, you can pass an optional block to `delete`.
52
+ The yielded object is a [Mail](https://github.com/mikel/mail) instance of the current mail providing many methods.
53
+ However, wrapping the mail into a nice `Mail` object is slow and you should avoid to use it if you can.
23
54
 
24
55
  ```ruby
25
- require 'imap_guard'
26
- load File.expand_path('../settings.rb', __FILE__)
27
- settings = SETTINGS.merge({ read_only: true })
28
-
29
- s = IMAPGuard::Guard.new settings
30
- s.select 'INBOX.ops'
31
-
32
- query = IMAPGuard::Query.new.before(7).subject("abc").from("root")
33
- s.delete query
34
-
35
- pattern = "monit alert -- Resource limit "
36
- query = IMAPGuard::Query.new.subject(pattern).before(7)
37
- s.delete query do |mail|
38
- # the pattern given to subject() is a mere string
39
- # pass an optional block to perform advanced filtering such as regexp matching
40
- # the yielded mail object is an instance of the current mail providing many methods
41
- mail.subject.start_with? pattern
56
+ guard.delete base_query.dup.before(7).subject("Logwatch for ") do |mail|
57
+ mail.subject =~ /\ALogwatch for \w \(Linux\)\Z/ and \
58
+ mail.multipart? and \
59
+ mail.parts.length == 2
42
60
  end
61
+ ```
43
62
 
44
- query = IMAPGuard::Query.new.before(7).subject("Logwatch for ")
45
- s.delete query do |mail|
46
- mail.subject =~ /\ALogwatch for \w \(Linux\)\Z/
47
- end
63
+ Finally, you can always forge your own raw IMAP search queries (the [RFC](http://tools.ietf.org/html/rfc3501#section-6.4.4) can help in that case):
48
64
 
49
- # You can also forge your own raw IMAP search queries like this
65
+ ```ruby
50
66
  query = 'SEEN SUBJECT "ALERT" FROM "root"'
51
- s.delete query do |mail|
52
- mail.subject == "ALERT" and \
67
+ guard.delete query do |mail|
53
68
  mail.body == "ALERT"
54
69
  end
70
+ ```
71
+
72
+ Be aware that emails won't be touched until you `expunge` or `close` the mailbox:
55
73
 
56
- s.close
74
+ ```ruby
75
+ guard.expunge # effectively delete emails marked as deleted
76
+ guard.close # expunge then close the connection
77
+ ```
78
+
79
+ Oh, and there is a `move` method as well:
80
+
81
+ ```ruby
82
+ guard.move query, 'destination_folder' do |mail|
83
+ # and it can take a filter block like `delete`
84
+ end
57
85
  ```
58
86
 
59
87
  ## Contributing
60
88
 
61
- 1. Fork it
62
- 2. Create your feature branch (`git checkout -b my-new-feature`)
63
- 3. Commit your changes (`git commit -am 'Add some feature'`)
64
- 4. Push to the branch (`git push origin my-new-feature`)
65
- 5. Create new Pull Request
89
+ Bug reports and patches are most welcome.
90
+
91
+ ## License
92
+
93
+ MIT
94
+
data/Rakefile CHANGED
@@ -1 +1,9 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec) do |t|
5
+ t.ruby_opts = '-w'
6
+ end
7
+
8
+ task default: :spec
9
+
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["cedric@felizard.fr"]
11
11
  spec.description = %q{A guard for your IMAP server}
12
12
  spec.summary = spec.description
13
- spec.homepage = ""
13
+ spec.homepage = "https://github.com/infertux/imap_guard"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
@@ -19,7 +19,14 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency 'mail', '~> 2.5.3'
22
+ spec.add_dependency 'colored', '~> 1.2'
22
23
 
23
24
  spec.add_development_dependency 'bundler', '~> 1.3'
24
25
  spec.add_development_dependency 'rake'
26
+ spec.add_development_dependency 'simplecov'
27
+ spec.add_development_dependency 'rspec'
28
+ spec.add_development_dependency 'guard-rspec'
29
+ spec.add_development_dependency 'rb-inotify'
30
+ spec.add_development_dependency 'cane'
31
+ spec.add_development_dependency 'yard'
25
32
  end
@@ -1,15 +1,21 @@
1
1
  require 'net/imap'
2
- require 'mail'
3
2
  require 'ostruct'
3
+ require 'mail'
4
+ require 'colored'
4
5
 
5
6
  module IMAPGuard
6
7
  class Guard
8
+ attr_reader :settings
9
+
7
10
  def initialize settings
8
- @settings = OpenStruct.new(settings).freeze
11
+ self.settings = settings
12
+ end
9
13
 
10
- # http://www.ruby-doc.org/stdlib-1.9.3/libdoc/net/imap/rdoc/Net/IMAP.html#method-c-new
14
+ # @see http://www.ruby-doc.org/stdlib-1.9.3/libdoc/net/imap/rdoc/Net/IMAP.html#method-c-new
15
+ def login
11
16
  @imap = Net::IMAP.new(@settings.host, @settings.port, true, nil, false)
12
17
  @imap.login(@settings.username, @settings.password)
18
+ verbose.puts "Logged in successfully"
13
19
  end
14
20
 
15
21
  def select mailbox
@@ -20,51 +26,97 @@ module IMAPGuard
20
26
  end
21
27
  end
22
28
 
23
- def delete query
24
- unless query.is_a? String
25
- if query.respond_to? :to_s
26
- query = query.to_s
27
- else
28
- raise ArgumentError, "query must provide #to_s"
29
- end
30
- end
29
+ # @param mailbox Destination mailbox
30
+ def move query, mailbox, &filter
31
+ operation = lambda { |message_id|
32
+ @imap.copy(message_id, mailbox) unless @settings.read_only
33
+ @imap.store(message_id, "+FLAGS", [:Deleted])
34
+ "moved to #{mailbox}".cyan
35
+ }
36
+ process query, operation, &filter
37
+ end
31
38
 
32
- messages = @imap.search query
33
- count = messages.size
34
- puts "Query: #{query.inspect}: #{count} results"
35
-
36
- counter = 0
37
- messages.each do |message_id|
38
- counter += 1
39
- # puts message_id
40
- mail = nil
39
+ def delete query, &filter
40
+ operation = lambda { |message_id|
41
+ @imap.store(message_id, "+FLAGS", [:Deleted])
42
+ 'deleted'.red
43
+ }
44
+ process query, operation, &filter
45
+ end
46
+
47
+ def expunge
48
+ @imap.expunge
49
+ end
50
+
51
+ def close
52
+ puts "Expunging deleted messages and closing mailbox..."
53
+ @imap.close
54
+ end
55
+
56
+ private
57
+
58
+ def process query, operation
59
+ message_ids = search query
60
+ count = message_ids.size
61
+
62
+ message_ids.each_with_index do |message_id, index|
63
+ print "Processing UID #{message_id} (#{index + 1}/#{count}): "
64
+
65
+ result = true
41
66
  if block_given?
42
- msg = @imap.fetch(message_id, 'RFC822')[0].attr['RFC822']
43
- mail = Mail.read_from_string msg
44
- result = yield mail
45
- if result
46
- # puts "Given filter matched"
47
- else
48
- # puts "Given filter returned falsy"
49
- next
50
- end
67
+ mail = fetch_mail message_id
68
+ result = yield(mail)
69
+ verbose.print "(given filter result: #{result.inspect}) "
51
70
  end
52
71
 
53
- print "Deleting UID #{message_id} (#{counter}/#{count})"
54
- print " (DRY-RUN)" if @settings.read_only
55
- if mail
56
- puts ": #{mail.subject} (#{mail.body.to_s.length})"
72
+ if result
73
+ puts operation.call(message_id)
57
74
  else
58
- puts
75
+ puts "ignored".yellow
59
76
  end
60
- @imap.store(message_id, "+FLAGS", [:Deleted])
61
77
  end
62
78
  end
63
79
 
64
- def close
65
- puts "Expunging deleted messages and closing mailbox..."
66
- # p imap.expunge
67
- @imap.close
80
+ def fetch_mail message_id
81
+ msg = @imap.fetch(message_id, 'RFC822')[0].attr['RFC822']
82
+ Mail.read_from_string msg
83
+ end
84
+
85
+ def search query
86
+ unless [Array, String].any? { |type| query.is_a? type }
87
+ raise ArgumentError, "query must be either a string holding the entire search string, or a single-dimension array of search keywords and arguments"
88
+ end
89
+
90
+ messages = @imap.search query
91
+ puts "Query: #{query.inspect}: #{messages.count} results".cyan
92
+
93
+ messages
94
+ end
95
+
96
+ def verbose
97
+ @verbose ||= if @settings.verbose
98
+ $stdout
99
+ else
100
+ # anonymous null object
101
+ Class.new do
102
+ def method_missing(*args, &block)
103
+ nil
104
+ end
105
+ end.new
106
+ end
107
+ end
108
+
109
+ def settings= settings
110
+ required = %w(host port username password).map!(&:to_sym)
111
+ missing = required - settings.keys
112
+ raise ArgumentError, "Missing settings: #{missing}" unless missing.empty?
113
+
114
+ optional = %w(read_only verbose).map!(&:to_sym)
115
+ unknown = settings.keys - required - optional
116
+ raise ArgumentError, "Unknown settings: #{unknown}" unless unknown.empty?
117
+
118
+ @settings = OpenStruct.new(settings).freeze
119
+ puts "DRY-RUN MODE ENABLED".yellow.bold.reversed if @settings.read_only
68
120
  end
69
121
  end
70
122
  end
@@ -1,49 +1,38 @@
1
1
  module IMAPGuard
2
- class Query
3
- def initialize
4
- @criteria = []
5
- seen.unanswered.unflagged
6
- end
7
-
8
- def to_s
9
- @criteria.join ' '
10
- end
11
-
2
+ class Query < Array
12
3
  def seen
13
- @criteria << 'SEEN'
14
- self
4
+ self << 'SEEN'
15
5
  end
16
6
 
17
7
  def unanswered
18
- @criteria << 'UNANSWERED'
19
- self
8
+ self << 'UNANSWERED'
20
9
  end
21
10
 
22
11
  def unflagged
23
- @criteria << 'UNFLAGGED'
24
- self
12
+ self << 'UNFLAGGED'
25
13
  end
26
14
 
27
15
  def subject string
28
- @criteria << "SUBJECT \"#{string}\""
29
- self
16
+ self << 'SUBJECT' << string
30
17
  end
31
18
 
32
19
  def from string
33
- @criteria << "FROM \"#{string}\""
34
- self
20
+ self << 'FROM' << string
35
21
  end
36
22
 
37
23
  def before date
38
24
  case date
25
+ when String
26
+ # noop, uses it as is
39
27
  when Fixnum
40
28
  date = (Date.today - date).strftime '%e-%b-%Y'
41
29
  when Date
42
- date = Date.strptime date, '%e-%b-%Y'
30
+ date = date.strftime '%e-%b-%Y'
31
+ else
32
+ raise ArgumentError, "#{date.inspect} is invalid"
43
33
  end
44
34
 
45
- @criteria << "BEFORE #{date}"
46
- self
35
+ self << 'BEFORE' << date
47
36
  end
48
37
  end
49
38
  end
@@ -1,3 +1,3 @@
1
1
  module ImapGuard
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,197 @@
1
+ require 'spec_helper'
2
+
3
+ module IMAPGuard
4
+ describe Guard do
5
+ before do
6
+ $stdout = StringIO.new # mute stdout - comment to debug
7
+ end
8
+
9
+ let(:settings) do
10
+ {
11
+ host: 'localhost',
12
+ port: 993,
13
+ username: 'bob',
14
+ password: 'PASS',
15
+ }
16
+ end
17
+
18
+ let(:imap) {
19
+ double('Net::IMAP', search: [7, 28])
20
+ }
21
+
22
+ def guard_instance custom_settings = {}
23
+ guard = Guard.new(settings.merge(custom_settings))
24
+ guard.instance_variable_set(:@imap, imap)
25
+ guard.stub(:fetch_mail)
26
+ guard
27
+ end
28
+
29
+ describe "#select" do
30
+ context "with settings.read_only = true" do
31
+ let(:guard) { guard_instance(read_only: true) }
32
+
33
+ it "opens the mailbox in read-only" do
34
+ imap.should_receive(:examine)
35
+ guard.select nil
36
+ end
37
+ end
38
+
39
+ context "with settings.read_only = false" do
40
+ let(:guard) { guard_instance(read_only: false) }
41
+
42
+ it "opens the mailbox in read-write" do
43
+ imap.should_receive(:select)
44
+ guard.select nil
45
+ end
46
+ end
47
+ end
48
+
49
+ describe "#search" do
50
+ before do
51
+ imap.should_receive(:search) do |arg|
52
+ [13, 37] if [['ALL'], 'ALL'].include? arg
53
+ end
54
+ end
55
+
56
+ it "accepts arrays" do
57
+ expect {
58
+ guard_instance.send(:search, ['ALL'])
59
+ }.to_not raise_error
60
+ end
61
+
62
+ it "accepts strings" do
63
+ expect {
64
+ guard_instance.send(:search, 'ALL')
65
+ }.to_not raise_error
66
+ end
67
+
68
+ it "returns results" do
69
+ messages = guard_instance.send(:search, 'ALL')
70
+ messages.should eq [13, 37]
71
+ end
72
+ end
73
+
74
+ describe "#process" do
75
+ let(:guard) { guard_instance(verbose: true) }
76
+ let(:opeartion) { ->(id) {} }
77
+
78
+ context "without a filter block" do
79
+ it "does perform the operation" do
80
+ opeartion.should_receive(:call).with(7)
81
+ opeartion.should_receive(:call).with(28)
82
+
83
+ guard.send(:process, 'ALL', opeartion)
84
+ end
85
+
86
+ it "does not execute the filter block" do
87
+ guard.should_not_receive(:fetch_mail)
88
+
89
+ guard.send(:process, 'ALL', opeartion)
90
+ end
91
+ end
92
+
93
+ context "with a filter block" do
94
+ it "executes the filter block" do
95
+ guard.should_receive(:fetch_mail).twice
96
+
97
+ guard.send(:process, 'ALL', opeartion) { }
98
+ end
99
+
100
+ context "returning false" do
101
+ it "does not perform the operation" do
102
+ opeartion.should_not_receive(:call)
103
+
104
+ guard.send(:process, 'ALL', opeartion) { false }
105
+ end
106
+ end
107
+
108
+ context "returning true" do
109
+ it "does perform the operation" do
110
+ opeartion.should_receive(:call).twice
111
+
112
+ guard.send(:process, 'ALL', opeartion) { true }
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ describe "#move" do
119
+ it "copies emails before adding the :Deleted flag" do
120
+ imap.should_receive(:search)
121
+ imap.should_receive(:copy).with(7, 'destination').ordered
122
+ imap.should_receive(:store).with(7, '+FLAGS', [:Deleted]).ordered
123
+ imap.should_receive(:copy).with(28, 'destination').ordered
124
+ imap.should_receive(:store).with(28, '+FLAGS', [:Deleted]).ordered
125
+
126
+ guard_instance.move 'ALL', 'destination'
127
+ end
128
+ end
129
+
130
+ describe "#delete" do
131
+ it "adds the :Deleted flag" do
132
+ imap.should_receive(:search)
133
+ imap.should_receive(:store).with(7, '+FLAGS', [:Deleted])
134
+ imap.should_receive(:store).with(28, '+FLAGS', [:Deleted])
135
+
136
+ guard_instance.delete 'ALL'
137
+ end
138
+ end
139
+
140
+ describe "#expunge" do
141
+ it "expunges the folder" do
142
+ imap.should_receive(:expunge)
143
+ guard_instance.expunge
144
+ end
145
+ end
146
+
147
+ describe "#close" do
148
+ it "closes the IMAP connection" do
149
+ imap.should_receive(:close)
150
+ guard_instance.close
151
+ end
152
+ end
153
+
154
+ describe "#verbose" do
155
+ context "with settings.verbose = true" do
156
+ let(:guard) { guard_instance(verbose: true) }
157
+
158
+ it "does output to $stdout" do
159
+ $stdout.should_receive(:write).with("ham")
160
+ guard.send(:verbose).print "ham"
161
+ end
162
+ end
163
+
164
+ context "with settings.verbose = false" do
165
+ let(:guard) { guard_instance(verbose: false) }
166
+
167
+ it "does not output to $stdout" do
168
+ $stdout.should_not_receive(:write)
169
+ guard.send(:verbose).print "ham"
170
+ end
171
+ end
172
+ end
173
+
174
+ describe "#settings=" do
175
+ it "freezes the settings" do
176
+ guard = Guard.new(settings)
177
+
178
+ expect {
179
+ guard.settings.host = 'example.net'
180
+ }.to raise_error(TypeError, /frozen/)
181
+ end
182
+
183
+ it "raises ArgumentError if any required key is missing" do
184
+ expect {
185
+ Guard.new({})
186
+ }.to raise_error ArgumentError, /missing/i
187
+ end
188
+
189
+ it "raises ArgumentError if any key is unknown" do
190
+ expect {
191
+ Guard.new(settings.merge(coffee: true))
192
+ }.to raise_error ArgumentError, /unknown/i
193
+ end
194
+ end
195
+ end
196
+ end
197
+
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ module IMAPGuard
4
+ describe Query do
5
+ describe "#initialize" do
6
+ it { should be_empty }
7
+ end
8
+
9
+ describe "#seen" do
10
+ it "adds 'SEEN'" do
11
+ subject.seen
12
+ subject.last.should eq 'SEEN'
13
+ end
14
+ end
15
+
16
+ describe "#unanswered" do
17
+ it "adds 'UNANSWERED'" do
18
+ subject.unanswered
19
+ subject.last.should eq 'UNANSWERED'
20
+ end
21
+ end
22
+
23
+ describe "#unflagged" do
24
+ it "adds 'UNFLAGGED'" do
25
+ subject.unflagged
26
+ subject.last.should eq 'UNFLAGGED'
27
+ end
28
+ end
29
+
30
+ describe "#subject" do
31
+ it "adds the search value" do
32
+ subject.subject("Hey you")
33
+ subject.last.should eq "Hey you"
34
+ end
35
+ end
36
+
37
+ describe "#from" do
38
+ it "adds the search value" do
39
+ subject.from("root@example.net")
40
+ subject.last.should eq "root@example.net"
41
+ end
42
+ end
43
+
44
+ describe "#before" do
45
+ context "when I pass 'nil' as an argument" do
46
+ it "raises" do
47
+ expect {
48
+ subject.before(nil)
49
+ }.to raise_error ArgumentError
50
+ end
51
+ end
52
+
53
+ context "when I pass '1' as an argument" do
54
+ it "returns yesterday" do
55
+ subject.before(1)
56
+ Date.parse(subject.last).should eq Date.today.prev_day
57
+ end
58
+ end
59
+
60
+ context "when I pass an integer" do
61
+ it "uses it as a negative offset in days" do
62
+ subject.before(3)
63
+ (Date.today - Date.parse(subject.last)).should eq 3
64
+ end
65
+ end
66
+
67
+ context "when I pass '18-Mar-2013' as an argument" do
68
+ it "uses it as is" do
69
+ subject.before('18-Mar-2013')
70
+ subject.last.should eq '18-Mar-2013'
71
+ end
72
+ end
73
+
74
+ context "when I pass an instance of Date as an argument" do
75
+ it "extracts the date" do
76
+ subject.before(Date.today)
77
+ Date.parse(subject.last).should eq Date.today
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+
@@ -0,0 +1,11 @@
1
+ require 'simplecov'
2
+ SimpleCov.start do
3
+ minimum_coverage 90
4
+ add_group "Sources", "lib"
5
+ add_group "Tests", "spec"
6
+ end
7
+
8
+ require 'imap_guard'
9
+
10
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |file| require file }
11
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imap_guard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
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-03-19 00:00:00.000000000 Z
12
+ date: 2013-03-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mail
@@ -27,6 +27,22 @@ dependencies:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
29
  version: 2.5.3
30
+ - !ruby/object:Gem::Dependency
31
+ name: colored
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.2'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.2'
30
46
  - !ruby/object:Gem::Dependency
31
47
  name: bundler
32
48
  requirement: !ruby/object:Gem::Requirement
@@ -59,6 +75,102 @@ dependencies:
59
75
  - - ! '>='
60
76
  - !ruby/object:Gem::Version
61
77
  version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: simplecov
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rspec
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: guard-rspec
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: rb-inotify
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: cane
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ - !ruby/object:Gem::Dependency
159
+ name: yard
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
62
174
  description: A guard for your IMAP server
63
175
  email:
64
176
  - cedric@felizard.fr
@@ -67,8 +179,11 @@ extensions: []
67
179
  extra_rdoc_files: []
68
180
  files:
69
181
  - .gitignore
182
+ - .rspec
70
183
  - .ruby-version
184
+ - .travis.yml
71
185
  - Gemfile
186
+ - Guardfile
72
187
  - LICENSE.txt
73
188
  - README.md
74
189
  - Rakefile
@@ -77,7 +192,10 @@ files:
77
192
  - lib/imap_guard/guard.rb
78
193
  - lib/imap_guard/query.rb
79
194
  - lib/imap_guard/version.rb
80
- homepage: ''
195
+ - spec/imap_guard/guard_spec.rb
196
+ - spec/imap_guard/query_spec.rb
197
+ - spec/spec_helper.rb
198
+ homepage: https://github.com/infertux/imap_guard
81
199
  licenses:
82
200
  - MIT
83
201
  post_install_message:
@@ -92,7 +210,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
92
210
  version: '0'
93
211
  segments:
94
212
  - 0
95
- hash: -502947235
213
+ hash: -500228931
96
214
  required_rubygems_version: !ruby/object:Gem::Requirement
97
215
  none: false
98
216
  requirements:
@@ -101,11 +219,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
219
  version: '0'
102
220
  segments:
103
221
  - 0
104
- hash: -502947235
222
+ hash: -500228931
105
223
  requirements: []
106
224
  rubyforge_project:
107
225
  rubygems_version: 1.8.25
108
226
  signing_key:
109
227
  specification_version: 3
110
228
  summary: A guard for your IMAP server
111
- test_files: []
229
+ test_files:
230
+ - spec/imap_guard/guard_spec.rb
231
+ - spec/imap_guard/query_spec.rb
232
+ - spec/spec_helper.rb
233
+ has_rdoc: