maid 0.8.0.alpha.4 → 0.9.0.alpha.1
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.
- checksums.yaml +7 -0
- data/.github/workflows/test.yml +36 -0
- data/.ruby-gemset +1 -1
- data/.ruby-version +1 -1
- data/AUTHORS.md +1 -0
- data/ChangeLog +11 -1
- data/README.md +6 -7
- data/Vagrantfile +1 -2
- data/lib/maid/app.rb +21 -0
- data/lib/maid/maid.rb +2 -2
- data/lib/maid/repeat.rb +3 -2
- data/lib/maid/rules.sample.rb +1 -1
- data/lib/maid/tools.rb +7 -7
- data/lib/maid/version.rb +1 -1
- data/maid.gemspec +18 -17
- data/script/vagrant-test-all +2 -2
- data/spec/dependency_spec.rb +1 -1
- data/spec/lib/maid/app_spec.rb +67 -17
- data/spec/lib/maid/maid_spec.rb +15 -0
- data/spec/lib/maid/tools_spec.rb +128 -110
- data/spec/lib/maid/trash_migration_spec.rb +21 -15
- data/spec/spec_helper.rb +1 -0
- metadata +204 -128
- data/.travis.yml +0 -15
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a8b5cb25bc23bd40980cdb281cc427eb1d8adaf81e8aa446abe0e93f7d127d7f
|
4
|
+
data.tar.gz: 69ebef7303be657252cc2076bb997db24bf417880e35c14a2735a167f7d9d361
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d48b3b39672ca83f12b5b78a0412529a3abdd8e2124db420fef1bfc2d50a80cef817ba88e1cdc2c2a73fab755c472776a50fbf531d2d4ff9337a5beae0d2f9cd
|
7
|
+
data.tar.gz: b92797a56fc213b486c962c097e1ddddc03bcdd5d50cc5a3ce4f96ffe7f26b288a374c41b071a4b297f30882159c427868c53f222177cd7c2b48eb7b26dc587b
|
@@ -0,0 +1,36 @@
|
|
1
|
+
name: Maid
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
pull_request:
|
8
|
+
branches:
|
9
|
+
- master
|
10
|
+
|
11
|
+
jobs:
|
12
|
+
test:
|
13
|
+
strategy:
|
14
|
+
matrix:
|
15
|
+
os:
|
16
|
+
- ubuntu-20.04
|
17
|
+
- ubuntu-22.04
|
18
|
+
- macos-11
|
19
|
+
- macos-12
|
20
|
+
ruby-version:
|
21
|
+
- 2.7
|
22
|
+
- 3.0
|
23
|
+
- 3.1
|
24
|
+
- 3.2
|
25
|
+
runs-on: ${{ matrix.os }}
|
26
|
+
steps:
|
27
|
+
- uses: actions/checkout@v3
|
28
|
+
- name: Set up Ruby
|
29
|
+
uses: ruby/setup-ruby@v1
|
30
|
+
with:
|
31
|
+
ruby-version: ${{ matrix.ruby-version }}
|
32
|
+
bundler-cache: true
|
33
|
+
- name: Install dependencies
|
34
|
+
run: bundle install
|
35
|
+
- name: Run tests
|
36
|
+
run: bundle exec rake
|
data/.ruby-gemset
CHANGED
@@ -1 +1 @@
|
|
1
|
-
maid
|
1
|
+
maid-dev
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3.1.3
|
data/AUTHORS.md
CHANGED
data/ChangeLog
CHANGED
@@ -1,6 +1,14 @@
|
|
1
|
+
maid (0.9.0) unstable; urgency=low
|
2
|
+
* Mark Przepiora: Support passing scheduler options to Rufus
|
3
|
+
* Pierre Rock: Support Ruby 3
|
4
|
+
* Pierre Rock: Update most dependencies
|
5
|
+
|
6
|
+
-- Pierre Rock <coaxial@users.noreply.github.com> Sat, 18 Mar 2023 12:06:00
|
7
|
+
+0100
|
8
|
+
|
1
9
|
maid (0.8.0) unstable; urgency=low
|
2
10
|
|
3
|
-
* Started official support for Ruby 2.2
|
11
|
+
* Started official support for Ruby 2.2 - 2.6. (Closes: #174)
|
4
12
|
* Song Chen Wen: Added OSX tagging tools (depends on `brew install tag`):
|
5
13
|
"tags", "has_tags?", "contains_tag?", "add_tag", "remove_tag", "set_tag"
|
6
14
|
(Closes: #125)
|
@@ -8,8 +16,10 @@ maid (0.8.0) unstable; urgency=low
|
|
8
16
|
tools, using OSX Spotlight metadata when available
|
9
17
|
* Song Chen Wen: Added Aria2 and Tunder support to "downloading?" tool
|
10
18
|
* Song Chen Wen: Reduce "watch" CPU usage by throttling (Closes: #149, #150)
|
19
|
+
* Phylor: Add command to manage logs (Closes: #169, #143)
|
11
20
|
* Updated development dependencies, except for FakeFS (help appreciated!)
|
12
21
|
* Updated dependencies: "listen", "rufus-scheduler"
|
22
|
+
* Phylor: Fix geolookup
|
13
23
|
|
14
24
|
-- Benjamin Oakes <hello@benjaminoakes.com> TODO
|
15
25
|
|
data/README.md
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
# Maid
|
2
2
|
|
3
|
-
[](https://codeclimate.com/github/benjaminoakes/maid)
|
3
|
+
[](http://badge.fury.io/rb/maid)
|
4
|
+
[](http://travis-ci.org/benjaminoakes/maid)
|
5
|
+
[](https://codeclimate.com/github/benjaminoakes/maid)
|
7
6
|
[](https://hakiri.io/github/benjaminoakes/maid/stable)
|
8
7
|
[](http://stackoverflow.com/questions/tagged/maid)
|
9
8
|
|
@@ -86,7 +85,7 @@ Modern Ruby versions and Unix-like operating systems should work, but only OS X
|
|
86
85
|
Offically supported:
|
87
86
|
|
88
87
|
* **OS:** Mac OS X, Ubuntu
|
89
|
-
* **Ruby:**
|
88
|
+
* **Ruby:** 2.7.0+ (3.0.0+ preferred)
|
90
89
|
|
91
90
|
Some features require OS X. See the [documentation][] for more details.
|
92
91
|
|
@@ -99,7 +98,7 @@ Consider `rbenv` or `rvm`, especially if only Ruby 1.8.7 is available (e.g. if y
|
|
99
98
|
System Ruby works fine too, though:
|
100
99
|
|
101
100
|
* **Mac OS X:** Ruby 2.0.0 comes preinstalled in OS X 10.9.
|
102
|
-
* **Ubuntu:** Ruby is not preinstalled. To install Ruby
|
101
|
+
* **Ubuntu:** Ruby is not preinstalled. To install Ruby 2.7: `sudo apt-get install ruby2.7`
|
103
102
|
([Interested in a package?](https://github.com/benjaminoakes/maid/issues/3))
|
104
103
|
|
105
104
|
Then, you can install via RubyGems. Open a terminal and run:
|
@@ -137,7 +136,7 @@ For example, this is a rule:
|
|
137
136
|
Maid.rules do
|
138
137
|
rule 'Old files downloaded while developing/testing' do
|
139
138
|
dir('~/Downloads/*').each do |path|
|
140
|
-
if downloaded_from(path).any? {|u| u.match 'http://localhost'} && 1.week.since?(
|
139
|
+
if downloaded_from(path).any? {|u| u.match 'http://localhost'} && 1.week.since?(accessed_at(path))
|
141
140
|
trash(path)
|
142
141
|
end
|
143
142
|
end
|
data/Vagrantfile
CHANGED
@@ -3,8 +3,7 @@
|
|
3
3
|
|
4
4
|
Vagrant.configure('2') do |config|
|
5
5
|
# See also: `script/vagrant-test`, `script/vagrant-test-all`
|
6
|
-
config.vm.box = ENV['MAID_TARGET_BOX'] || 'precise64'
|
7
|
-
config.vm.box_url = 'http://files.vagrantup.com/precise64.box' if 'precise64' == config.vm.box
|
6
|
+
config.vm.box = ENV['MAID_TARGET_BOX'] || 'hashicorp/precise64'
|
8
7
|
|
9
8
|
config.vm.provider :virtualbox do |vb|
|
10
9
|
# Maid has very low system requirements
|
data/lib/maid/app.rb
CHANGED
@@ -93,6 +93,27 @@ EOF
|
|
93
93
|
maid.daemonize
|
94
94
|
end
|
95
95
|
|
96
|
+
desc 'logs', 'Manages logs written by maid'
|
97
|
+
method_option :path, :type => :boolean, :aliases => %w(-p)
|
98
|
+
method_option :tail, :type => :boolean, :aliases => %w(-t)
|
99
|
+
def logs
|
100
|
+
maid = Maid::Maid.new(maid_options(options))
|
101
|
+
|
102
|
+
if options.path?
|
103
|
+
say maid.log_device
|
104
|
+
else
|
105
|
+
unless File.readable?(maid.log_device)
|
106
|
+
error "Log file #{maid.log_device} does not exist."
|
107
|
+
else
|
108
|
+
if options.tail?
|
109
|
+
system("tail -f #{maid.log_device}")
|
110
|
+
else
|
111
|
+
say `tail #{maid.log_device}`
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
96
117
|
no_tasks do
|
97
118
|
def maid_options(options)
|
98
119
|
h = {}
|
data/lib/maid/maid.rb
CHANGED
@@ -89,8 +89,8 @@ class Maid::Maid
|
|
89
89
|
@watches << ::Maid::Watch.new(self, path, options, &rules)
|
90
90
|
end
|
91
91
|
|
92
|
-
def repeat(timestring, &rules)
|
93
|
-
@repeats << ::Maid::Repeat.new(self, timestring, &rules)
|
92
|
+
def repeat(timestring, options = {}, &rules)
|
93
|
+
@repeats << ::Maid::Repeat.new(self, timestring, options, &rules)
|
94
94
|
end
|
95
95
|
|
96
96
|
# Daemonizes the process by starting all watches and repeats and joining
|
data/lib/maid/repeat.rb
CHANGED
@@ -4,17 +4,18 @@ class Maid::Repeat
|
|
4
4
|
|
5
5
|
attr_reader :timestring, :scheduler, :logger
|
6
6
|
|
7
|
-
def initialize(maid, timestring, &rules)
|
7
|
+
def initialize(maid, timestring, options = {}, &rules)
|
8
8
|
@maid = maid
|
9
9
|
@logger = maid.logger # TODO: Maybe it's better to create seperate loggers?
|
10
10
|
@scheduler = Rufus::Scheduler.singleton
|
11
11
|
@timestring = timestring
|
12
|
+
@options = options
|
12
13
|
initialize_rules(&rules)
|
13
14
|
end
|
14
15
|
|
15
16
|
def run
|
16
17
|
unless rules.empty?
|
17
|
-
@scheduler.repeat(timestring) { follow_rules }
|
18
|
+
@scheduler.repeat(timestring, @options) { follow_rules }
|
18
19
|
end
|
19
20
|
end
|
20
21
|
|
data/lib/maid/rules.sample.rb
CHANGED
@@ -40,7 +40,7 @@ Maid.rules do
|
|
40
40
|
|
41
41
|
rule 'Mac OS X applications in zip files' do
|
42
42
|
found = dir('~/Downloads/*.zip').select { |path|
|
43
|
-
zipfile_contents(path).any? { |c| c.match(/\.app
|
43
|
+
zipfile_contents(path).any? { |c| c.match(/\.app\/Contents\//) }
|
44
44
|
}
|
45
45
|
|
46
46
|
trash(found)
|
data/lib/maid/tools.rb
CHANGED
@@ -3,7 +3,7 @@ require 'find'
|
|
3
3
|
require 'fileutils'
|
4
4
|
require 'time'
|
5
5
|
|
6
|
-
require 'exifr'
|
6
|
+
require 'exifr/jpeg'
|
7
7
|
require 'geocoder'
|
8
8
|
require 'mime/types'
|
9
9
|
require 'dimensions'
|
@@ -39,16 +39,16 @@ module Maid::Tools
|
|
39
39
|
# move(['~/Downloads/foo.zip', '~/Downloads/bar.zip'], '~/Archive/Software/Mac OS X/')
|
40
40
|
# move(dir('~/Downloads/*.zip'), '~/Archive/Software/Mac OS X/')
|
41
41
|
def move(sources, destination)
|
42
|
-
|
42
|
+
expanded_destination = expand(destination)
|
43
43
|
|
44
|
-
if File.directory?(
|
44
|
+
if File.directory?(expanded_destination)
|
45
45
|
expand_all(sources).each do |source|
|
46
|
-
log("move #{ sh_escape(source) } #{ sh_escape(
|
47
|
-
FileUtils.mv(source,
|
46
|
+
log("move #{ sh_escape(source) } #{ sh_escape(expanded_destination) }")
|
47
|
+
FileUtils.mv(source, expanded_destination, @file_options)
|
48
48
|
end
|
49
49
|
else
|
50
50
|
# Unix `mv` warns about the target not being a directory with multiple sources. Maid checks the same.
|
51
|
-
warn("skipping move because #{ sh_escape(
|
51
|
+
warn("skipping move because #{ sh_escape(expanded_destination) } is not a directory (use 'mkdir' to create first, or use 'rename')")
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -456,7 +456,7 @@ module Maid::Tools
|
|
456
456
|
gps = EXIFR::JPEG.new(path).gps
|
457
457
|
coordinates_string = [gps.latitude, gps.longitude]
|
458
458
|
location = Geocoder.search(coordinates_string).first
|
459
|
-
[location.city, location.province, location.country_code].join(', ')
|
459
|
+
[location.city, location.province, location.country_code.upcase].join(', ')
|
460
460
|
end
|
461
461
|
end
|
462
462
|
|
data/lib/maid/version.rb
CHANGED
data/maid.gemspec
CHANGED
@@ -15,43 +15,44 @@ Gem::Specification.new do |s|
|
|
15
15
|
|
16
16
|
s.rubyforge_project = 'maid'
|
17
17
|
|
18
|
-
s.required_ruby_version = '>=
|
18
|
+
s.required_ruby_version = '>= 2.7.0'
|
19
19
|
|
20
20
|
# Strategy: if possible, use ranges (so there are fewer chances of version conflicts)
|
21
21
|
s.add_dependency('escape', '>= 0.0.1', '< 0.1.0') # Used for better Ruby 1.8.7 support, could be replaced with `Shellwords`
|
22
|
-
s.add_dependency('thor', '
|
22
|
+
s.add_dependency('thor', '~> 1.2.1')
|
23
23
|
s.add_dependency('deprecated', '~> 3.0.0')
|
24
24
|
s.add_dependency('dimensions', '>= 1.0.0', '< 2.0')
|
25
|
-
s.add_dependency('mime-types', '~>
|
26
|
-
s.add_dependency('rubyzip', '~>
|
25
|
+
s.add_dependency('mime-types', '~> 3.0', '< 4.0')
|
26
|
+
s.add_dependency('rubyzip', '~> 2.3.2')
|
27
27
|
s.add_dependency('xdg', '~> 2.2.3') # previous versions had bugs
|
28
|
-
s.add_dependency('listen', '
|
29
|
-
s.add_dependency('rufus-scheduler', '
|
30
|
-
s.add_dependency('exifr', '~> 1.
|
31
|
-
s.add_dependency('geocoder', '~> 1.
|
32
|
-
|
28
|
+
s.add_dependency('listen', '~> 3.8.0')
|
29
|
+
s.add_dependency('rufus-scheduler', '~> 3.8.2')
|
30
|
+
s.add_dependency('exifr', '~> 1.3.10')
|
31
|
+
s.add_dependency('geocoder', '~> 1.8.1')
|
32
|
+
|
33
33
|
# TODO: use one of these two gems instead of `mdfind`. **But** They have to work on Linux as well.
|
34
34
|
#
|
35
35
|
# s.add_dependency('mac-spotlight', '~> 0.0.4')
|
36
36
|
# s.add_dependency('spotlight', '~> 0.0.6')
|
37
37
|
|
38
38
|
# Strategy: specific versions (since they're just for development)
|
39
|
-
s.add_development_dependency('fakefs', '~>
|
39
|
+
s.add_development_dependency('fakefs', '~> 2.4.0')
|
40
40
|
s.add_development_dependency('guard', '~> 2.12.5')
|
41
41
|
s.add_development_dependency('guard-rspec', '~> 4.6.2')
|
42
|
-
s.add_development_dependency('rake', '~>
|
43
|
-
s.add_development_dependency('redcarpet', '~> 3.
|
44
|
-
s.add_development_dependency('rspec', '~> 3.
|
45
|
-
s.add_development_dependency('timecop', '~> 0.
|
46
|
-
s.add_development_dependency('yard', '
|
42
|
+
s.add_development_dependency('rake', '~> 13.0.6')
|
43
|
+
s.add_development_dependency('redcarpet', '~> 3.6.0') # Soft dependency of `yard`
|
44
|
+
s.add_development_dependency('rspec', '~> 3.12.0')
|
45
|
+
s.add_development_dependency('timecop', '~> 0.9.6')
|
46
|
+
s.add_development_dependency('yard', '>= 0.9.11')
|
47
|
+
s.add_development_dependency('pry-byebug')
|
47
48
|
|
48
49
|
# In Vagrant, polling won't cross over the OS boundary if you develop in the host OS but run your tests in the
|
49
50
|
# guest. One way around this is to force polling instead:
|
50
51
|
#
|
51
52
|
# bundle exec guard --force-polling
|
52
53
|
#
|
53
|
-
s.add_development_dependency('rb-inotify', '~> 0.
|
54
|
-
s.add_development_dependency('rb-fsevent', '~> 0.
|
54
|
+
s.add_development_dependency('rb-inotify', '~> 0.10.1')
|
55
|
+
s.add_development_dependency('rb-fsevent', '~> 0.11.2')
|
55
56
|
|
56
57
|
s.files = `git ls-files -z`.split("\0")
|
57
58
|
s.test_files = `git ls-files -z -- {test,spec,features}/*`.split("\0")
|
data/script/vagrant-test-all
CHANGED
@@ -28,7 +28,7 @@
|
|
28
28
|
# * [Vagrant Boxes List](http://www.vagrantbox.es/)
|
29
29
|
# * [Contributing Guide](https://github.com/benjaminoakes/maid/wiki/Contributing)
|
30
30
|
|
31
|
-
MAID_TARGET_BOX='precise32' MAID_TARGET_RUBY='1.9.3' script/vagrant-test
|
32
|
-
MAID_TARGET_BOX='precise64' MAID_TARGET_RUBY='1.9.3' script/vagrant-test
|
31
|
+
MAID_TARGET_BOX='hashicorp/precise32' MAID_TARGET_RUBY='1.9.3' script/vagrant-test
|
32
|
+
MAID_TARGET_BOX='hashicorp/precise64' MAID_TARGET_RUBY='1.9.3' script/vagrant-test
|
33
33
|
# TODO: Locate and add box for `saucy32`
|
34
34
|
# TODO: Locate and add box for `saucy64`
|
data/spec/dependency_spec.rb
CHANGED
data/spec/lib/maid/app_spec.rb
CHANGED
@@ -1,25 +1,26 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'stringio'
|
3
3
|
|
4
|
+
def capture_stdout
|
5
|
+
out = StringIO.new
|
6
|
+
$stdout = out
|
7
|
+
yield
|
8
|
+
out.string
|
9
|
+
ensure
|
10
|
+
$stdout = STDOUT
|
11
|
+
end
|
12
|
+
|
13
|
+
def capture_stderr
|
14
|
+
out = StringIO.new
|
15
|
+
$stderr = out
|
16
|
+
yield
|
17
|
+
out.string
|
18
|
+
ensure
|
19
|
+
$stderr = STDERR
|
20
|
+
end
|
21
|
+
|
4
22
|
module Maid
|
5
23
|
describe App, '#clean' do
|
6
|
-
def capture_stdout
|
7
|
-
out = StringIO.new
|
8
|
-
$stdout = out
|
9
|
-
yield
|
10
|
-
out.string
|
11
|
-
ensure
|
12
|
-
$stdout = STDOUT
|
13
|
-
end
|
14
|
-
|
15
|
-
def capture_stderr
|
16
|
-
out = StringIO.new
|
17
|
-
$stderr = out
|
18
|
-
yield
|
19
|
-
out.string
|
20
|
-
ensure
|
21
|
-
$stderr = STDERR
|
22
|
-
end
|
23
24
|
|
24
25
|
before do
|
25
26
|
@app = App.new
|
@@ -124,4 +125,53 @@ module Maid
|
|
124
125
|
expect(opts[:rules_path]).to match(/maid_rules.rb$/)
|
125
126
|
end
|
126
127
|
end
|
128
|
+
|
129
|
+
describe App, '#logs' do
|
130
|
+
before do
|
131
|
+
@maid = double('Maid')
|
132
|
+
@maid.stub(:clean)
|
133
|
+
@maid.stub(:log_device) { '/var/log/maid.log' }
|
134
|
+
@maid.stub(:load_rules)
|
135
|
+
Maid.stub(:new) { @maid }
|
136
|
+
end
|
137
|
+
|
138
|
+
describe 'prints out the log' do
|
139
|
+
before do
|
140
|
+
@log = "A maid log\nAnother log"
|
141
|
+
@log_file = Tempfile.new('maid.log')
|
142
|
+
@log_file.write(@log)
|
143
|
+
@log_file.close
|
144
|
+
|
145
|
+
@maid.stub(:log_device) { @log_file.path }
|
146
|
+
end
|
147
|
+
|
148
|
+
after do
|
149
|
+
@log_file.unlink if !@log_file.nil?
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'dumps the last log entries when invoked without an option' do
|
153
|
+
expect(capture_stdout { App.start(['logs']) }).to eq("#{@log}\n")
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'prints an error when log does not exist' do
|
157
|
+
@maid.stub(:log_device) { '/maid/file-does-not-exist' }
|
158
|
+
message = "Log file #{@maid.log_device} does not exist.\n"
|
159
|
+
|
160
|
+
expect(capture_stderr { App.start(['logs']) }).to eq(message)
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'does not tail when log does not exist' do
|
164
|
+
@maid.stub(:log_device) { '/maid/file-does-not-exist' }
|
165
|
+
message = "Log file #{@maid.log_device} does not exist.\n"
|
166
|
+
|
167
|
+
expect(capture_stderr { App.start(['logs', '--tail']) }).to eq(message)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'prints out the log path' do
|
172
|
+
['--path', '-p'].each do |option|
|
173
|
+
expect(capture_stdout { App.start(['logs', option]) }).to eq("/var/log/maid.log\n")
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
127
177
|
end
|
data/spec/lib/maid/maid_spec.rb
CHANGED
@@ -231,6 +231,21 @@ module Maid
|
|
231
231
|
expect(@maid.repeats.length).to eq(1)
|
232
232
|
expect(@maid.repeats.first.timestring).to eq('1s')
|
233
233
|
end
|
234
|
+
|
235
|
+
it 'accepts a hash of options and passes them to Rufus' do
|
236
|
+
scheduler = double('scheduler')
|
237
|
+
expect(Rufus::Scheduler).to receive(:singleton).and_return(scheduler)
|
238
|
+
|
239
|
+
hash = { :some => :options }
|
240
|
+
@maid.repeat('1s', hash) do
|
241
|
+
rule 'test' do
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
expect(scheduler).to receive(:repeat).with('1s', hash)
|
246
|
+
|
247
|
+
@maid.repeats.last.run
|
248
|
+
end
|
234
249
|
end
|
235
250
|
|
236
251
|
describe '#follow_rules' do
|