maid 0.1.0.beta2 → 0.1.0.beta.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -1
- data/CONTRIBUTING.rdoc +12 -0
- data/Gemfile.lock +32 -0
- data/Maidfile +4 -0
- data/README.rdoc +42 -23
- data/lib/maid.rb +1 -3
- data/lib/maid/app.rb +6 -3
- data/lib/maid/maid.rb +47 -15
- data/lib/maid/numeric_extensions.rb +13 -0
- data/lib/maid/tools.rb +18 -14
- data/lib/maid/version.rb +1 -1
- data/maid.gemspec +2 -1
- data/spec/lib/maid/app_spec.rb +35 -2
- data/spec/lib/maid/maid_spec.rb +28 -8
- data/spec/lib/maid/numeric_extensions_spec.rb +11 -0
- data/spec/lib/maid/tools_spec.rb +19 -11
- metadata +34 -15
data/.gitignore
CHANGED
data/CONTRIBUTING.rdoc
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
= Contributing
|
2
|
+
|
3
|
+
This is a Ruby Gem, built using Bundler. For a walkthrough of how that works, see http://railscasts.com/episodes/245-new-gem-with-bundler.
|
4
|
+
|
5
|
+
== Notes
|
6
|
+
|
7
|
+
* `rake install` builds and installs the gem, but you'll probably need to do `sudo rake install`.
|
8
|
+
* Keep in mind that the gemspec only looks at files in the VCS (git).
|
9
|
+
|
10
|
+
== Guidelines
|
11
|
+
|
12
|
+
* Whenever possible, retain compatibility with Ruby 1.8.
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
maid (0.1.0.beta.3)
|
5
|
+
thor (~> 0.14.6)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
ZenTest (4.4.2)
|
11
|
+
diff-lcs (1.1.2)
|
12
|
+
rake (0.8.7)
|
13
|
+
rspec (2.5.0)
|
14
|
+
rspec-core (~> 2.5.0)
|
15
|
+
rspec-expectations (~> 2.5.0)
|
16
|
+
rspec-mocks (~> 2.5.0)
|
17
|
+
rspec-core (2.5.2)
|
18
|
+
rspec-expectations (2.5.0)
|
19
|
+
diff-lcs (~> 1.1.2)
|
20
|
+
rspec-mocks (2.5.0)
|
21
|
+
thor (0.14.6)
|
22
|
+
timecop (0.3.5)
|
23
|
+
|
24
|
+
PLATFORMS
|
25
|
+
ruby
|
26
|
+
|
27
|
+
DEPENDENCIES
|
28
|
+
ZenTest (~> 4.4.2)
|
29
|
+
maid!
|
30
|
+
rake (~> 0.8.7)
|
31
|
+
rspec (~> 2.5.0)
|
32
|
+
timecop (~> 0.3.5)
|
data/Maidfile
ADDED
data/README.rdoc
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
= Maid
|
2
2
|
|
3
|
-
Maid
|
3
|
+
Be lazy! Let Maid clean up after you, based on rules you define.
|
4
4
|
|
5
|
-
|
5
|
+
Maid keeps files from sitting around too long, untouched. Many of the downloads and other files you collect can easily be categorized and handled appropriately by rules you define. Let the maid in your computer take care of the easy stuff, so you can spend more of your time on what matters.
|
6
6
|
|
7
|
-
Worried about things happening that you don't expect?
|
7
|
+
Think of it like the email filters you might already have, but for files. Worried about things happening that you don't expect? Maid doesn't overwrite files and actions are logged so you can tell what happened.
|
8
8
|
|
9
9
|
Maid is inspired by the Mac OS X shareware program Hazel[http://www.noodlesoft.com/hazel.php]. This tool was created on Mac OS X 10.6, but should be generally portable to other systems. (Some of the more advanced features such as <tt>downloaded_from</tt> require OS X, however.)
|
10
10
|
|
@@ -12,23 +12,43 @@ Your rules are defined in Ruby, so easy rules are easy and difficult rules are p
|
|
12
12
|
|
13
13
|
== Installation
|
14
14
|
|
15
|
-
|
15
|
+
Maid is currently in beta, but I encourage you to give it a try. I'm using it on several computers daily.
|
16
16
|
|
17
|
-
|
17
|
+
If you have RubyGems installed (default on Mac OS X and many Ruby installations):
|
18
18
|
|
19
|
-
|
19
|
+
gem install maid --pre
|
20
20
|
|
21
|
-
|
21
|
+
If you want to install the executable for all users, you may need to give root access:
|
22
22
|
|
23
|
-
|
23
|
+
sudo gem install maid --pre
|
24
|
+
|
25
|
+
=== Ubuntu, et al.
|
26
|
+
|
27
|
+
As you might expect, you need Ruby and RubyGems installed to do the above.
|
28
|
+
|
29
|
+
sudo apt-get install ruby
|
30
|
+
sudo apt-get install rubygems
|
31
|
+
|
32
|
+
You might also need to add the RubyGems <tt>bin</tt> directory to your <tt>$PATH</tt>. For example, on Ubuntu you might need to add something like this to your <tt>~/.bashrc</tt>:
|
33
|
+
|
34
|
+
export PATH="/var/lib/gems/1.8/bin:$PATH"
|
24
35
|
|
25
36
|
== Tutorial
|
26
37
|
|
27
|
-
Maid
|
38
|
+
Maid rules are defined using Ruby, with some common operations made easier with a small DSL (Domain Specific Language). Here's a sample:
|
39
|
+
|
40
|
+
Maid.rules do
|
41
|
+
rule 'Old files downloaded while developing/testing' do
|
42
|
+
dir('~/Downloads/*').each do |path|
|
43
|
+
if downloaded_from(path).any? {|u| u.match 'http://localhost'} && 1.week.since? last_accessed(path)
|
44
|
+
trash(path)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
28
49
|
|
29
|
-
Before you start running your rules, you'll likely want to
|
50
|
+
Before you start running your rules, you'll likely want to be able to test them. Here's how:
|
30
51
|
|
31
|
-
# Do a "dry run" of your rules.
|
32
52
|
# No actions are taken; you just see what would happen with your rules as defined.
|
33
53
|
maid --dry-run
|
34
54
|
maid --noop
|
@@ -42,9 +62,9 @@ To run your rules on demand, you can run <tt>maid</tt> manually:
|
|
42
62
|
So, for example, if this is <tt>some_rules.rb</tt>:
|
43
63
|
|
44
64
|
Maid.rules do
|
45
|
-
rule '
|
65
|
+
rule 'downloaded PDF books' do
|
46
66
|
dir('~/Downloads/*.pdf').each do |path|
|
47
|
-
move(path,
|
67
|
+
move(path, '~/Books')
|
48
68
|
end
|
49
69
|
end
|
50
70
|
end
|
@@ -52,26 +72,25 @@ So, for example, if this is <tt>some_rules.rb</tt>:
|
|
52
72
|
This is the command to test, as well as some sample output:
|
53
73
|
|
54
74
|
$ maid -nr some_rules.rb
|
55
|
-
|
56
|
-
|
57
|
-
mv "/Users/ben/Downloads/
|
58
|
-
mv "/Users/ben/Downloads/
|
59
|
-
mv "/Users/ben/Downloads/issue12.pdf" "/Users/ben/Downloads/issue12.pdf"
|
60
|
-
mv "/Users/ben/Downloads/spring2011newsletter.pdf" "/Users/ben/Downloads/spring2011newsletter.pdf"
|
61
|
-
Finished
|
75
|
+
Rule: downloaded PDF books
|
76
|
+
mv "/Users/ben/Downloads/book.pdf" "/Users/ben/Books/"
|
77
|
+
mv "/Users/ben/Downloads/issue12.pdf" "/Users/ben/Books/"
|
78
|
+
mv "/Users/ben/Downloads/spring2011newsletter.pdf" "/Users/ben/Books/"
|
62
79
|
|
63
|
-
For more helper methods, please see the documentation of Maid::Tools.
|
80
|
+
For more DSL helper methods, please see the documentation of Maid::Tools.
|
64
81
|
|
65
82
|
=== Automation
|
66
83
|
|
67
|
-
Once you get a hang for what you can do with Maid,
|
84
|
+
Once you get a hang for what you can do with Maid, let it do its stuff automatically throughout the day. You'll find your computer stays a little tidier with as you teach it how to handle your common files.
|
68
85
|
|
69
86
|
To do this, edit your crontab in your tool of choice and have it invoke the <tt>maid</tt> command. The <tt>--silent</tt> option is provided to keep this from emailing you, if desired. A log of the actions taken is kept at <tt>~/.maid/maid.log</tt>.
|
70
87
|
|
71
88
|
Example for every day at 1am:
|
72
89
|
|
73
90
|
# minute hour day_of_month month day_of_week command_to_execute
|
74
|
-
0 1 * * * bash -li -c "maid --silent"
|
91
|
+
0 1 * * * /bin/bash -li -c "maid --silent"
|
92
|
+
|
93
|
+
Both Mac OS X and Linux support callbacks when folders are changed, and that may be a forthcoming feature in Maid. That said, I find cron to take care of most of my needs.
|
75
94
|
|
76
95
|
== Sample and Ideas
|
77
96
|
|
data/lib/maid.rb
CHANGED
data/lib/maid/app.rb
CHANGED
@@ -2,6 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'thor'
|
3
3
|
|
4
4
|
class Maid::App < Thor
|
5
|
+
check_unknown_options!
|
5
6
|
default_task 'clean'
|
6
7
|
|
7
8
|
desc 'clean', 'Clean based on rules'
|
@@ -10,11 +11,13 @@ class Maid::App < Thor
|
|
10
11
|
method_option :silent, :type => :boolean, :aliases => %w[-s]
|
11
12
|
def clean
|
12
13
|
maid = Maid::Maid.new(maid_options(options))
|
13
|
-
|
14
|
+
unless options.silent? || options.noop?
|
15
|
+
say "Logging actions to #{maid.log_device.inspect}"
|
16
|
+
end
|
14
17
|
maid.clean
|
15
18
|
end
|
16
19
|
|
17
|
-
desc 'version', '
|
20
|
+
desc 'version', 'Print version number'
|
18
21
|
def version
|
19
22
|
say Maid::VERSION
|
20
23
|
end
|
@@ -26,7 +29,7 @@ class Maid::App < Thor
|
|
26
29
|
if options['noop']
|
27
30
|
# You're testing, so a simple log goes to STDOUT and no actions are taken
|
28
31
|
h[:file_options] = {:noop => true}
|
29
|
-
h[:
|
32
|
+
h[:log_device] = STDOUT
|
30
33
|
h[:log_formatter] = lambda { |_, _, _, msg| "#{msg}\n" }
|
31
34
|
end
|
32
35
|
|
data/lib/maid/maid.rb
CHANGED
@@ -4,33 +4,33 @@ require 'logger'
|
|
4
4
|
# Maid cleans up according to the given rules, logging what it does.
|
5
5
|
class Maid::Maid
|
6
6
|
DEFAULTS = {
|
7
|
-
:progname
|
8
|
-
:
|
9
|
-
:rules_path
|
10
|
-
:trash_path
|
7
|
+
:progname => 'Maid',
|
8
|
+
:log_device => File.expand_path('~/.maid/maid.log'),
|
9
|
+
:rules_path => File.expand_path('~/.maid/rules.rb'),
|
10
|
+
:trash_path => File.expand_path('~/.Trash'),
|
11
11
|
:file_options => {:noop => true}, # for FileUtils
|
12
12
|
}.freeze
|
13
13
|
|
14
|
+
attr_reader :file_options, :log_device, :rules, :rules_path, :trash_path
|
14
15
|
include ::Maid::Tools
|
15
|
-
attr_reader :file_options, :log_path, :rules, :rules_path, :trash_path
|
16
16
|
|
17
17
|
# Make a new Maid, setting up paths for the log and trash.
|
18
18
|
#
|
19
19
|
# Sane defaults for a log and trash path are set for Mac OS X, but they can easily be overridden like so:
|
20
20
|
#
|
21
|
-
# Maid::Maid.new(:
|
21
|
+
# Maid::Maid.new(:log_device => '/home/username/log/maid.log', :trash_path => '/home/username/.local/share/Trash/files/')
|
22
22
|
#
|
23
23
|
def initialize(options = {})
|
24
24
|
options = DEFAULTS.merge(options.reject { |k, v| v.nil? })
|
25
25
|
|
26
|
-
@
|
27
|
-
FileUtils.mkdir_p(File.dirname(@
|
28
|
-
@logger = Logger.new(@
|
29
|
-
@logger.progname
|
26
|
+
@log_device = options[:log_device]
|
27
|
+
FileUtils.mkdir_p(File.dirname(@log_device)) unless @log_device.kind_of?(IO)
|
28
|
+
@logger = Logger.new(@log_device)
|
29
|
+
@logger.progname = options[:progname]
|
30
30
|
@logger.formatter = options[:log_formatter] if options[:log_formatter]
|
31
31
|
|
32
|
-
@rules_path
|
33
|
-
@trash_path
|
32
|
+
@rules_path = options[:rules_path]
|
33
|
+
@trash_path = options[:trash_path]
|
34
34
|
@file_options = options[:file_options]
|
35
35
|
|
36
36
|
@rules = []
|
@@ -38,18 +38,28 @@ class Maid::Maid
|
|
38
38
|
|
39
39
|
# Start cleaning, based on the rules defined at rules_path.
|
40
40
|
def clean
|
41
|
-
@
|
41
|
+
unless @log_device.kind_of?(IO)
|
42
|
+
@logger.info "v#{Maid::VERSION}"
|
43
|
+
@logger.info 'Started'
|
44
|
+
end
|
45
|
+
|
42
46
|
add_rules(@rules_path)
|
43
47
|
follow_rules
|
44
|
-
|
48
|
+
|
49
|
+
unless @log_device.kind_of?(IO)
|
50
|
+
@logger.info 'Finished'
|
51
|
+
end
|
45
52
|
end
|
46
53
|
|
47
54
|
# Add the rules at path.
|
48
55
|
def add_rules(path)
|
49
56
|
Maid.with_instance(self) do
|
50
57
|
# Using 'Kernel' here to help with testability
|
51
|
-
Kernel.
|
58
|
+
# Kernel.load must be used for non-".rb" files to be required, it seems.
|
59
|
+
Kernel.load(path)
|
52
60
|
end
|
61
|
+
rescue LoadError => e
|
62
|
+
STDERR.puts e.message
|
53
63
|
end
|
54
64
|
|
55
65
|
# Register a rule with a description and instructions (lambda function).
|
@@ -64,4 +74,26 @@ class Maid::Maid
|
|
64
74
|
rule.follow
|
65
75
|
end
|
66
76
|
end
|
77
|
+
|
78
|
+
# Run a shell command.
|
79
|
+
#--
|
80
|
+
# Delegates to Kernel.`. Made primarily for testing other commands and some error handling.
|
81
|
+
def cmd(command) #:nodoc:
|
82
|
+
if supported_command?(command)
|
83
|
+
%x(#{command})
|
84
|
+
else
|
85
|
+
raise ArgumentError, "Unsupported command: #{command.inspect}"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
# Does the OS support this command?
|
92
|
+
def supported_command?(command) #:nodoc:
|
93
|
+
@@supported_commands ||= {}
|
94
|
+
|
95
|
+
command_name = command.strip.split(/\s+/)[0]
|
96
|
+
supported = @@supported_commands[command_name]
|
97
|
+
@@supported_commands[command_name] = supported ? supported : !%x(which #{command_name}).empty?
|
98
|
+
end
|
67
99
|
end
|
@@ -73,4 +73,17 @@ module Maid::NumericExtensions
|
|
73
73
|
|
74
74
|
# Reads best without arguments: 10.minutes.from_now
|
75
75
|
alias :from_now :since
|
76
|
+
|
77
|
+
######################
|
78
|
+
### Maid additions ###
|
79
|
+
######################
|
80
|
+
|
81
|
+
# TODO find a better place for these to live?
|
82
|
+
|
83
|
+
# Reads well in a case like:
|
84
|
+
#
|
85
|
+
# 1.week.since? last_accessed('filename')
|
86
|
+
def since?(other_time)
|
87
|
+
other_time < self.ago
|
88
|
+
end
|
76
89
|
end
|
data/lib/maid/tools.rb
CHANGED
@@ -5,6 +5,8 @@ require 'time'
|
|
5
5
|
# Collection of utility methods included in Maid::Maid (and thus available in the rules DSL).
|
6
6
|
#
|
7
7
|
# In general, all paths are automatically expanded (e.g. '~/Downloads/foo.zip' becomes '/home/username/Downloads/foo.zip').
|
8
|
+
#
|
9
|
+
# Some methods are not available on all platforms. An <tt>ArgumentError</tt> is raised when a command is not available. See tags: [Mac OS X]
|
8
10
|
module Maid::Tools
|
9
11
|
# Move from <tt>from</tt> to <tt>to</tt>.
|
10
12
|
#
|
@@ -62,14 +64,16 @@ module Maid::Tools
|
|
62
64
|
Find.find(File.expand_path(path), &block)
|
63
65
|
end
|
64
66
|
|
65
|
-
#
|
67
|
+
# [Mac OS X] Use Spotlight to locate all files matching the given filename.
|
66
68
|
#
|
67
|
-
#
|
68
|
-
|
69
|
-
|
69
|
+
# locate('foo.zip') # => ['/a/foo.zip', '/b/foo.zip']
|
70
|
+
#--
|
71
|
+
# TODO use `locate` elsewhere -- it isn't available by default on OS X starting with OS X Leopard.
|
72
|
+
def locate(name)
|
73
|
+
cmd("mdfind -name #{name.inspect}").split("\n")
|
70
74
|
end
|
71
75
|
|
72
|
-
# Use Spotlight metadata to determine the site from which a file was downloaded.
|
76
|
+
# [Mac OS X] Use Spotlight metadata to determine the site from which a file was downloaded.
|
73
77
|
#
|
74
78
|
# downloaded_from('foo.zip') # => ['http://www.site.com/foo.zip', 'http://www.site.com/']
|
75
79
|
def downloaded_from(path)
|
@@ -78,20 +82,13 @@ module Maid::Tools
|
|
78
82
|
clean.split(/,\s+/).map { |s| t = s.strip; t[1, t.length - 2] }
|
79
83
|
end
|
80
84
|
|
81
|
-
# Use Spotlight metadata to determine audio length.
|
85
|
+
# [Mac OS X] Use Spotlight metadata to determine audio length.
|
82
86
|
#
|
83
87
|
# duration_s('foo.mp3') # => 235.705
|
84
88
|
def duration_s(path)
|
85
89
|
cmd("mdls -raw -name kMDItemDurationSeconds #{path.inspect}").to_f
|
86
90
|
end
|
87
91
|
|
88
|
-
# Use Spotlight to locate all files matching the given filename
|
89
|
-
#
|
90
|
-
# locate('foo.zip') # => ['/a/foo.zip', '/b/foo.zip']
|
91
|
-
def locate(name)
|
92
|
-
cmd("mdfind -name #{name.inspect}").split("\n")
|
93
|
-
end
|
94
|
-
|
95
92
|
# Inspect the contents of a .zip file.
|
96
93
|
#
|
97
94
|
# zipfile_contents('foo.zip') # => ['foo/foo.exe', 'foo/README.txt']
|
@@ -108,12 +105,19 @@ module Maid::Tools
|
|
108
105
|
raw.split(/\s+/).first.to_i
|
109
106
|
end
|
110
107
|
|
108
|
+
# In Unix speak, "atime".
|
109
|
+
#
|
110
|
+
# last_accessed('foo.zip') # => Sat Apr 09 10:50:01 -0400 2011
|
111
|
+
def last_accessed(path)
|
112
|
+
File.atime(File.expand_path(path))
|
113
|
+
end
|
114
|
+
|
111
115
|
# Pulls and pushes the given git repository.
|
112
116
|
#
|
113
117
|
# git_piston('~/code/projectname')
|
114
118
|
def git_piston(path)
|
115
119
|
full_path = File.expand_path(path)
|
116
120
|
stdout = cmd("cd #{full_path.inspect} && git pull && git push 2>&1")
|
117
|
-
@logger.info "Fired piston on #{full_path.inspect}. STDOUT:\n\n#{stdout}"
|
121
|
+
@logger.info "Fired git piston on #{full_path.inspect}. STDOUT:\n\n#{stdout}"
|
118
122
|
end
|
119
123
|
end
|
data/lib/maid/version.rb
CHANGED
data/maid.gemspec
CHANGED
@@ -9,12 +9,13 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.authors = ["Benjamin Oakes"]
|
10
10
|
s.email = ["hello@benjaminoakes.com"]
|
11
11
|
s.homepage = "http://github.com/benjaminoakes/maid"
|
12
|
-
s.summary = %q{Maid
|
12
|
+
s.summary = %q{Be lazy. Let Maid clean up after you, based on rules you define.}
|
13
13
|
s.description = s.summary
|
14
14
|
|
15
15
|
s.rubyforge_project = "maid"
|
16
16
|
|
17
17
|
s.add_dependency('thor', '~> 0.14.6')
|
18
|
+
s.add_development_dependency('rake', '~> 0.8.7')
|
18
19
|
s.add_development_dependency('rspec', '~> 2.5.0')
|
19
20
|
s.add_development_dependency('timecop', '~> 0.3.5')
|
20
21
|
s.add_development_dependency('ZenTest', '~> 4.4.2')
|
data/spec/lib/maid/app_spec.rb
CHANGED
@@ -1,15 +1,35 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'stringio'
|
2
3
|
|
3
4
|
module Maid
|
4
5
|
describe App, '#clean' do
|
6
|
+
def capture_stdout
|
7
|
+
out = StringIO.new
|
8
|
+
$stdout = out
|
9
|
+
yield
|
10
|
+
return out
|
11
|
+
ensure
|
12
|
+
$stdout = STDOUT
|
13
|
+
end
|
14
|
+
|
15
|
+
def capture_stderr
|
16
|
+
out = StringIO.new
|
17
|
+
$stderr = out
|
18
|
+
yield
|
19
|
+
return out
|
20
|
+
ensure
|
21
|
+
$stderr = STDERR
|
22
|
+
end
|
23
|
+
|
5
24
|
before :each do
|
6
25
|
@app = App.new
|
7
26
|
@app.stub!(:maid_options)
|
8
27
|
@app.stub!(:say)
|
9
28
|
|
29
|
+
# NOTE It's pretty important that this is stubbed, unless you want your rules to be run over and over when you test!
|
10
30
|
@maid = mock('Maid')
|
11
31
|
@maid.stub!(:clean)
|
12
|
-
@maid.stub!(:
|
32
|
+
@maid.stub!(:log_device)
|
13
33
|
Maid.stub!(:new).and_return(@maid)
|
14
34
|
end
|
15
35
|
|
@@ -24,6 +44,19 @@ module Maid
|
|
24
44
|
@maid.should_receive(:clean)
|
25
45
|
@app.clean
|
26
46
|
end
|
47
|
+
|
48
|
+
it 'should be silent if given the --silent option' do
|
49
|
+
# TODO It might even make sense to wrap "maid.clean" in capture_stdout { }...
|
50
|
+
capture_stdout { App.start(['clean', '--silent']) }.string.should == ''
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should complain about a MISSPELLED option' do
|
54
|
+
capture_stderr { App.start(['clean', '--slient']) }.string.should match(/Unknown/)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should complain about an undefined task' do
|
58
|
+
capture_stderr { App.start(['rules.rb']) }.string.should match(/Could not find/)
|
59
|
+
end
|
27
60
|
end
|
28
61
|
|
29
62
|
describe App, '#version' do
|
@@ -42,7 +75,7 @@ module Maid
|
|
42
75
|
it 'should log to STDOUT for testing purposes when given noop' do
|
43
76
|
opts = @app.maid_options('noop' => true)
|
44
77
|
opts[:file_options][:noop].should be_true
|
45
|
-
opts[:
|
78
|
+
opts[:log_device].should == STDOUT
|
46
79
|
opts[:log_formatter].call(nil, nil, nil, 'hello').should == "hello\n"
|
47
80
|
end
|
48
81
|
|
data/spec/lib/maid/maid_spec.rb
CHANGED
@@ -10,19 +10,19 @@ module Maid
|
|
10
10
|
|
11
11
|
describe '.new' do
|
12
12
|
it 'should set up a logger with the default path' do
|
13
|
-
Logger.should_receive(:new).with(Maid::DEFAULTS[:
|
13
|
+
Logger.should_receive(:new).with(Maid::DEFAULTS[:log_device])
|
14
14
|
Maid.new
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'should set up a logger with the given path, if provided' do
|
18
|
-
|
19
|
-
Logger.should_receive(:new).with(
|
20
|
-
Maid.new(:
|
18
|
+
log_device = '/var/log/maid.log'
|
19
|
+
Logger.should_receive(:new).with(log_device)
|
20
|
+
Maid.new(:log_device => log_device)
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'should make the log directory in case it does not exist' do
|
24
24
|
FileUtils.should_receive(:mkdir_p).with('/home/username/log')
|
25
|
-
Maid.new(:
|
25
|
+
Maid.new(:log_device => '/home/username/log/maid.log')
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'should set the trash to the default path' do
|
@@ -99,7 +99,7 @@ module Maid
|
|
99
99
|
|
100
100
|
describe '#add_rules' do
|
101
101
|
before :each do
|
102
|
-
Kernel.stub!(:
|
102
|
+
Kernel.stub!(:load)
|
103
103
|
@maid = Maid.new
|
104
104
|
end
|
105
105
|
|
@@ -108,11 +108,17 @@ module Maid
|
|
108
108
|
@maid.add_rules('path')
|
109
109
|
end
|
110
110
|
|
111
|
-
it 'should
|
111
|
+
it 'should load the path' do
|
112
112
|
path = 'rules.rb'
|
113
|
-
Kernel.should_receive(:
|
113
|
+
Kernel.should_receive(:load).with(path)
|
114
114
|
@maid.add_rules(path)
|
115
115
|
end
|
116
|
+
|
117
|
+
it 'should give an error on STDERR if there is a LoadError' do
|
118
|
+
Kernel.stub!(:load).and_raise(LoadError)
|
119
|
+
STDERR.should_receive(:puts)
|
120
|
+
@maid.add_rules('path')
|
121
|
+
end
|
116
122
|
end
|
117
123
|
|
118
124
|
describe '#rule' do
|
@@ -147,5 +153,19 @@ module Maid
|
|
147
153
|
maid.follow_rules
|
148
154
|
end
|
149
155
|
end
|
156
|
+
|
157
|
+
describe '#cmd' do
|
158
|
+
before :each do
|
159
|
+
@maid = Maid.new
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'should report `not-a-real-command` as not being a supported command' do
|
163
|
+
lambda { @maid.cmd('not-a-real-command arg1 arg2') }.should raise_error(ArgumentError)
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'should report `echo` as a real command' do
|
167
|
+
lambda { @maid.cmd('echo .') }.should_not raise_error(ArgumentError)
|
168
|
+
end
|
169
|
+
end
|
150
170
|
end
|
151
171
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Maid::NumericExtensions, '#since?' do
|
4
|
+
it 'should tell you that 1 week ago happened after 2 weeks ago' do
|
5
|
+
(1.week.since? 2.weeks.ago).should be_true
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should tell you that 2 weeks ago was not after 1 week ago' do
|
9
|
+
(2.week.since? 1.weeks.ago).should be_false
|
10
|
+
end
|
11
|
+
end
|
data/spec/lib/maid/tools_spec.rb
CHANGED
@@ -72,41 +72,49 @@ module Maid
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
+
describe '#locate' do
|
76
|
+
it 'should locate a file by name' do
|
77
|
+
@maid.should_receive(:cmd).and_return("/a/foo.zip\n/b/foo.zip\n")
|
78
|
+
@maid.locate('foo.zip').should == ['/a/foo.zip', '/b/foo.zip']
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
75
82
|
describe '#downloaded_from' do
|
76
|
-
it 'should
|
83
|
+
it 'should determine the download site' do
|
77
84
|
@maid.should_receive(:cmd).and_return(%Q{(\n "http://www.site.com/foo.zip",\n"http://www.site.com/"\n)})
|
78
85
|
@maid.downloaded_from('foo.zip').should == ['http://www.site.com/foo.zip', 'http://www.site.com/']
|
79
86
|
end
|
80
87
|
end
|
81
88
|
|
82
89
|
describe '#duration_s' do
|
83
|
-
it 'should
|
90
|
+
it 'should determine audio length' do
|
84
91
|
@maid.should_receive(:cmd).and_return('235.705')
|
85
92
|
@maid.duration_s('foo.mp3').should == 235.705
|
86
93
|
end
|
87
94
|
end
|
88
95
|
|
89
|
-
describe '#locate' do
|
90
|
-
it 'should use Spotlight to locate a file by name' do
|
91
|
-
@maid.should_receive(:cmd).and_return("/a/foo.zip\n/b/foo.zip\n")
|
92
|
-
@maid.locate('foo.zip').should == ['/a/foo.zip', '/b/foo.zip']
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
96
|
describe '#zipfile_contents' do
|
97
|
-
it 'should
|
97
|
+
it 'should inspect the contents of a .zip file' do
|
98
98
|
@maid.should_receive(:cmd).and_return("foo/foo.exe\nfoo/README.txt\n")
|
99
99
|
@maid.zipfile_contents('foo.zip').should == ['foo/foo.exe', 'foo/README.txt']
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
103
103
|
describe '#disk_usage' do
|
104
|
-
it 'should
|
104
|
+
it 'should give the disk usage of a file' do
|
105
105
|
@maid.should_receive(:cmd).and_return("136 foo.zip")
|
106
106
|
@maid.disk_usage('foo.zip').should == 136
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
110
|
+
describe '#last_accessed' do
|
111
|
+
it 'should give the last accessed time of the file' do
|
112
|
+
time = Time.now
|
113
|
+
File.should_receive(:atime).with("#@home/foo.zip").and_return(time)
|
114
|
+
@maid.last_accessed('~/foo.zip').should == time
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
110
118
|
describe '#git_piston' do
|
111
119
|
it 'should pull and push the given git repository, logging the action' do
|
112
120
|
@maid.should_receive(:cmd).with(%Q{cd "#@home/code/projectname" && git pull && git push 2>&1})
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: maid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 62196405
|
5
5
|
prerelease: 6
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
9
|
- 0
|
10
10
|
- beta
|
11
|
-
-
|
12
|
-
version: 0.1.0.
|
11
|
+
- 3
|
12
|
+
version: 0.1.0.beta.3
|
13
13
|
platform: ruby
|
14
14
|
authors:
|
15
15
|
- Benjamin Oakes
|
@@ -17,8 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2011-
|
21
|
-
default_executable:
|
20
|
+
date: 2011-06-02 00:00:00 Z
|
22
21
|
dependencies:
|
23
22
|
- !ruby/object:Gem::Dependency
|
24
23
|
name: thor
|
@@ -37,9 +36,25 @@ dependencies:
|
|
37
36
|
type: :runtime
|
38
37
|
version_requirements: *id001
|
39
38
|
- !ruby/object:Gem::Dependency
|
40
|
-
name:
|
39
|
+
name: rake
|
41
40
|
prerelease: false
|
42
41
|
requirement: &id002 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
hash: 49
|
47
|
+
segments:
|
48
|
+
- 0
|
49
|
+
- 8
|
50
|
+
- 7
|
51
|
+
version: 0.8.7
|
52
|
+
type: :development
|
53
|
+
version_requirements: *id002
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: rspec
|
56
|
+
prerelease: false
|
57
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
43
58
|
none: false
|
44
59
|
requirements:
|
45
60
|
- - ~>
|
@@ -51,11 +66,11 @@ dependencies:
|
|
51
66
|
- 0
|
52
67
|
version: 2.5.0
|
53
68
|
type: :development
|
54
|
-
version_requirements: *
|
69
|
+
version_requirements: *id003
|
55
70
|
- !ruby/object:Gem::Dependency
|
56
71
|
name: timecop
|
57
72
|
prerelease: false
|
58
|
-
requirement: &
|
73
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
59
74
|
none: false
|
60
75
|
requirements:
|
61
76
|
- - ~>
|
@@ -67,11 +82,11 @@ dependencies:
|
|
67
82
|
- 5
|
68
83
|
version: 0.3.5
|
69
84
|
type: :development
|
70
|
-
version_requirements: *
|
85
|
+
version_requirements: *id004
|
71
86
|
- !ruby/object:Gem::Dependency
|
72
87
|
name: ZenTest
|
73
88
|
prerelease: false
|
74
|
-
requirement: &
|
89
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
75
90
|
none: false
|
76
91
|
requirements:
|
77
92
|
- - ~>
|
@@ -83,8 +98,8 @@ dependencies:
|
|
83
98
|
- 2
|
84
99
|
version: 4.4.2
|
85
100
|
type: :development
|
86
|
-
version_requirements: *
|
87
|
-
description: Maid
|
101
|
+
version_requirements: *id005
|
102
|
+
description: Be lazy. Let Maid clean up after you, based on rules you define.
|
88
103
|
email:
|
89
104
|
- hello@benjaminoakes.com
|
90
105
|
executables:
|
@@ -96,8 +111,11 @@ extra_rdoc_files: []
|
|
96
111
|
files:
|
97
112
|
- .gitignore
|
98
113
|
- .rspec
|
114
|
+
- CONTRIBUTING.rdoc
|
99
115
|
- Gemfile
|
116
|
+
- Gemfile.lock
|
100
117
|
- LICENSE
|
118
|
+
- Maidfile
|
101
119
|
- README.rdoc
|
102
120
|
- Rakefile
|
103
121
|
- bin/maid
|
@@ -111,11 +129,11 @@ files:
|
|
111
129
|
- maid.gemspec
|
112
130
|
- spec/lib/maid/app_spec.rb
|
113
131
|
- spec/lib/maid/maid_spec.rb
|
132
|
+
- spec/lib/maid/numeric_extensions_spec.rb
|
114
133
|
- spec/lib/maid/rule_spec.rb
|
115
134
|
- spec/lib/maid/tools_spec.rb
|
116
135
|
- spec/lib/maid_spec.rb
|
117
136
|
- spec/spec_helper.rb
|
118
|
-
has_rdoc: true
|
119
137
|
homepage: http://github.com/benjaminoakes/maid
|
120
138
|
licenses: []
|
121
139
|
|
@@ -147,13 +165,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
165
|
requirements: []
|
148
166
|
|
149
167
|
rubyforge_project: maid
|
150
|
-
rubygems_version: 1.
|
168
|
+
rubygems_version: 1.7.2
|
151
169
|
signing_key:
|
152
170
|
specification_version: 3
|
153
|
-
summary: Maid
|
171
|
+
summary: Be lazy. Let Maid clean up after you, based on rules you define.
|
154
172
|
test_files:
|
155
173
|
- spec/lib/maid/app_spec.rb
|
156
174
|
- spec/lib/maid/maid_spec.rb
|
175
|
+
- spec/lib/maid/numeric_extensions_spec.rb
|
157
176
|
- spec/lib/maid/rule_spec.rb
|
158
177
|
- spec/lib/maid/tools_spec.rb
|
159
178
|
- spec/lib/maid_spec.rb
|