maid 0.1.2 → 0.1.3.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/.rspec +3 -0
- data/.travis.yml +1 -0
- data/Guardfile +8 -0
- data/README.md +103 -66
- data/Rakefile +4 -7
- data/Vagrantfile +11 -0
- data/lib/maid.rb +7 -1
- data/lib/maid/app.rb +53 -0
- data/lib/maid/maid.rb +32 -10
- data/lib/maid/numeric_extensions.rb +111 -73
- data/lib/maid/platform.rb +17 -0
- data/lib/maid/rules.sample.rb +44 -35
- data/lib/maid/tools.rb +179 -25
- data/lib/maid/trash_migration.rb +38 -0
- data/lib/maid/version.rb +1 -1
- data/maid.gemspec +16 -5
- data/resources/OneThingWell.png +0 -0
- data/resources/ruby5.gif +0 -0
- data/script/provision +22 -0
- data/spec/lib/maid/app_spec.rb +4 -6
- data/spec/lib/maid/maid_spec.rb +51 -26
- data/spec/lib/maid/numeric_extensions_spec.rb +15 -1
- data/spec/lib/maid/platform_spec.rb +44 -0
- data/spec/lib/maid/tools_spec.rb +233 -31
- data/spec/lib/maid/trash_migration_spec.rb +76 -0
- data/spec/lib/maid_spec.rb +4 -1
- data/spec/spec_helper.rb +9 -1
- metadata +147 -47
- data/CONTRIBUTING.rdoc +0 -25
- data/Gemfile.lock +0 -32
- data/configure +0 -7
- data/script/micro-maid.sh +0 -18
@@ -1,89 +1,127 @@
|
|
1
|
-
# From https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/numeric/time.rb, with some modifications since active_support ruins Logger by overriding its functionality.
|
2
1
|
module Maid::NumericExtensions
|
3
|
-
#
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
2
|
+
# From https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/numeric/time.rb, with some modifications since active_support ruins Logger by overriding its functionality.
|
3
|
+
module Time
|
4
|
+
# Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years.
|
5
|
+
#
|
6
|
+
# These methods use Time#advance for precise date calculations when using from_now, ago, etc.
|
7
|
+
# as well as adding or subtracting their results from a Time object. For example:
|
8
|
+
#
|
9
|
+
# # equivalent to Time.now.advance(:months => 1)
|
10
|
+
# 1.month.from_now
|
11
|
+
#
|
12
|
+
# # equivalent to Time.now.advance(:years => 2)
|
13
|
+
# 2.years.from_now
|
14
|
+
#
|
15
|
+
# # equivalent to Time.now.advance(:months => 4, :years => 5)
|
16
|
+
# (4.months + 5.years).from_now
|
17
|
+
#
|
18
|
+
# While these methods provide precise calculation when used as in the examples above, care
|
19
|
+
# should be taken to note that this is not true if the result of `months', `years', etc is
|
20
|
+
# converted before use:
|
21
|
+
#
|
22
|
+
# # equivalent to 30.days.to_i.from_now
|
23
|
+
# 1.month.to_i.from_now
|
24
|
+
#
|
25
|
+
# # equivalent to 365.25.days.to_f.from_now
|
26
|
+
# 1.year.to_f.from_now
|
27
|
+
#
|
28
|
+
# In such cases, Ruby's core
|
29
|
+
# Date[http://stdlib.rubyonrails.org/libdoc/date/rdoc/index.html] and
|
30
|
+
# Time[http://stdlib.rubyonrails.org/libdoc/time/rdoc/index.html] should be used for precision
|
31
|
+
# date and time arithmetic
|
32
|
+
def seconds
|
33
|
+
self
|
34
|
+
end
|
35
|
+
alias :second :seconds
|
35
36
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
def minutes
|
38
|
+
self * 60
|
39
|
+
end
|
40
|
+
alias :minute :minutes
|
40
41
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
42
|
+
def hours
|
43
|
+
self * 3600
|
44
|
+
end
|
45
|
+
alias :hour :hours
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
def days
|
48
|
+
self * 24.hours
|
49
|
+
end
|
50
|
+
alias :day :days
|
50
51
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
52
|
+
def weeks
|
53
|
+
self * 7.days
|
54
|
+
end
|
55
|
+
alias :week :weeks
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
def fortnights
|
58
|
+
self * 2.weeks
|
59
|
+
end
|
60
|
+
alias :fortnight :fortnights
|
60
61
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
62
|
+
# Reads best without arguments: 10.minutes.ago
|
63
|
+
def ago(time = ::Time.now)
|
64
|
+
time - self
|
65
|
+
end
|
66
|
+
|
67
|
+
# Reads best with argument: 10.minutes.until(time)
|
68
|
+
alias :until :ago
|
69
|
+
|
70
|
+
# Reads best with argument: 10.minutes.since(time)
|
71
|
+
def since(time = ::Time.now)
|
72
|
+
time + self
|
73
|
+
end
|
74
|
+
|
75
|
+
# Reads best without arguments: 10.minutes.from_now
|
76
|
+
alias :from_now :since
|
77
|
+
|
78
|
+
######################
|
79
|
+
### Maid additions ###
|
80
|
+
######################
|
65
81
|
|
66
|
-
|
67
|
-
alias :until :ago
|
82
|
+
# TODO find a better place for these to live?
|
68
83
|
|
69
|
-
|
70
|
-
|
71
|
-
|
84
|
+
# Reads well in a case like:
|
85
|
+
#
|
86
|
+
# 1.week.since? accessed_at('filename')
|
87
|
+
def since?(other_time)
|
88
|
+
other_time < self.ago
|
89
|
+
end
|
72
90
|
end
|
91
|
+
module SizeToKb
|
92
|
+
# Enables Computer disk size conversion into kilobytes.
|
93
|
+
#
|
94
|
+
# Can convert megabytes, gigabytes and terabytes.
|
95
|
+
# Handles full name (megabyte), plural (megabytes) and symobl (mb/mB).
|
96
|
+
#
|
97
|
+
# 1.megabyte = 1024 kilobytes
|
73
98
|
|
74
|
-
|
75
|
-
|
99
|
+
def kb
|
100
|
+
self
|
101
|
+
end
|
102
|
+
alias :kilobytes :kb
|
103
|
+
alias :kilobyte :kb
|
104
|
+
alias :kB :kb
|
76
105
|
|
77
|
-
|
78
|
-
|
79
|
-
|
106
|
+
def mb
|
107
|
+
self * 1024 ** 1
|
108
|
+
end
|
109
|
+
alias :megabytes :mb
|
110
|
+
alias :megabyte :mb
|
111
|
+
alias :mB :mb
|
80
112
|
|
81
|
-
|
113
|
+
def gb
|
114
|
+
self * 1024 ** 2
|
115
|
+
end
|
116
|
+
alias :gigabytes :gb
|
117
|
+
alias :gigabyte :gb
|
118
|
+
alias :gB :gb
|
82
119
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
120
|
+
def tb
|
121
|
+
self * 1024 ** 3
|
122
|
+
end
|
123
|
+
alias :terabytes :tb
|
124
|
+
alias :terabyte :tb
|
125
|
+
alias :tB :tb
|
88
126
|
end
|
89
127
|
end
|
data/lib/maid/rules.sample.rb
CHANGED
@@ -1,62 +1,71 @@
|
|
1
|
-
# Sample Maid rules file --
|
1
|
+
# Sample Maid rules file -- some ideas to get you started.
|
2
2
|
#
|
3
|
-
# To use, remove ".sample" from the filename. Test using:
|
3
|
+
# To use, remove ".sample" from the filename, and modify as desired. Test using:
|
4
4
|
#
|
5
|
-
# maid -n
|
5
|
+
# maid clean -n
|
6
6
|
#
|
7
|
-
#
|
7
|
+
# **NOTE:** It's recommended you just use this as a template; if you run these rules on your machine without knowing what they do, you might run into unwanted results!
|
8
|
+
#
|
9
|
+
# Don't forget, it's just Ruby! You can define custom methods and use them below:
|
10
|
+
#
|
11
|
+
# def magic(*)
|
12
|
+
# # ...
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# If you come up with some cool tools of your own, please send me a pull request on GitHub!
|
8
16
|
#
|
9
|
-
#
|
10
|
-
# * Read the README at http://github.com/benjaminoakes/maid
|
11
|
-
# * For more DSL helper methods, please see the documentation of Maid::Tools at http://rubydoc.info/gems/maid/0.1.0/Maid/Tools
|
12
|
-
# * Come up with some cool tools of your own? Fork, make your changes, and send me a pull request on GitHub!
|
13
|
-
# * Ask me a question over email (hello@benjaminoakes.com) or Twitter (@benjaminoakes)
|
17
|
+
# For more help on Maid:
|
14
18
|
#
|
19
|
+
# * Run `maid help`
|
20
|
+
# * Read the README, tutorial, and documentation at https://github.com/benjaminoakes/maid#maid
|
21
|
+
# * Ask me a question over email (hello@benjaminoakes.com) or Twitter (@benjaminoakes)
|
22
|
+
|
15
23
|
Maid.rules do
|
16
|
-
# NOTE
|
17
|
-
rule 'MP3s likely to be music' do
|
18
|
-
dir('~/Downloads/*.mp3').each do |path|
|
19
|
-
if duration_s(path) > 30.0
|
20
|
-
move(path, '~/Music/iTunes/iTunes Media/Automatically Add to iTunes/')
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
# NOTE: Currently, only Mac OS X supports `downloaded_from`.
|
26
|
-
rule 'Old files downloaded while developing/testing' do
|
27
|
-
dir('~/Downloads/*').each do |path|
|
28
|
-
if downloaded_from(path).any? {|u| u.match 'http://localhost' || u.match('http://staging.yourcompany.com') } && 1.week.since?(last_accessed(path))
|
29
|
-
trash(path)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
24
|
+
# **NOTE:** It's recommended you just use this as a template; if you run these rules on your machine without knowing what they do, you might run into unwanted results!
|
33
25
|
|
34
26
|
rule 'Linux ISOs, etc' do
|
35
|
-
dir('~/Downloads/*.iso')
|
27
|
+
trash(dir('~/Downloads/*.iso'))
|
36
28
|
end
|
37
29
|
|
38
30
|
rule 'Linux applications in Debian packages' do
|
39
|
-
dir('~/Downloads/*.deb')
|
31
|
+
trash(dir('~/Downloads/*.deb'))
|
40
32
|
end
|
41
33
|
|
42
34
|
rule 'Mac OS X applications in disk images' do
|
43
|
-
dir('~/Downloads/*.dmg')
|
35
|
+
trash(dir('~/Downloads/*.dmg'))
|
44
36
|
end
|
45
37
|
|
46
38
|
rule 'Mac OS X applications in zip files' do
|
47
|
-
dir('~/Downloads/*.zip').select
|
48
|
-
|
49
|
-
|
50
|
-
|
39
|
+
found = dir('~/Downloads/*.zip').select { |path|
|
40
|
+
zipfile_contents(path).any? { |c| c.match(/\.app$/) }
|
41
|
+
}
|
42
|
+
|
43
|
+
trash(found)
|
51
44
|
end
|
52
45
|
|
53
46
|
rule 'Misc Screenshots' do
|
54
47
|
dir('~/Desktop/Screen shot *').each do |path|
|
55
|
-
if 1.week.since?(
|
48
|
+
if 1.week.since?(accessed_at(path))
|
56
49
|
move(path, '~/Documents/Misc Screenshots/')
|
57
50
|
end
|
58
51
|
end
|
59
52
|
end
|
60
53
|
|
61
|
-
#
|
54
|
+
# NOTE: Currently, only Mac OS X supports `duration_s`.
|
55
|
+
rule 'MP3s likely to be music' do
|
56
|
+
dir('~/Downloads/*.mp3').each do |path|
|
57
|
+
if duration_s(path) > 30.0
|
58
|
+
move(path, '~/Music/iTunes/iTunes Media/Automatically Add to iTunes/')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# NOTE: Currently, only Mac OS X supports `downloaded_from`.
|
64
|
+
rule 'Old files downloaded while developing/testing' do
|
65
|
+
dir('~/Downloads/*').each do |path|
|
66
|
+
if downloaded_from(path).any? { |u| u.match('http://localhost') || u.match('http://staging.yourcompany.com') } && 1.week.since?(accessed_at(path))
|
67
|
+
trash(path)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
62
71
|
end
|
data/lib/maid/tools.rb
CHANGED
@@ -8,6 +8,8 @@ require 'time'
|
|
8
8
|
#
|
9
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]
|
10
10
|
module Maid::Tools
|
11
|
+
include Deprecated
|
12
|
+
|
11
13
|
# Move from <tt>from</tt> to <tt>to</tt>.
|
12
14
|
#
|
13
15
|
# The path is not moved if a file already exists at the destination with the same name. A warning is logged instead.
|
@@ -15,53 +17,139 @@ module Maid::Tools
|
|
15
17
|
# This method delegates to FileUtils. The instance-level <tt>file_options</tt> hash is passed to control the <tt>:noop</tt> option.
|
16
18
|
#
|
17
19
|
# move('~/Downloads/foo.zip', '~/Archive/Software/Mac OS X/')
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
20
|
+
#
|
21
|
+
# This method can handle multiple from paths.
|
22
|
+
#
|
23
|
+
# move(['~/Downloads/foo.zip', '~/Downloads/bar.zip'], '~/Archive/Software/Mac OS X/')
|
24
|
+
# move(dir('~/Downloads/*.zip'), '~/Archive/Software/Mac OS X/')
|
25
|
+
def move(froms, to)
|
26
|
+
Array(froms).each do |from|
|
27
|
+
from = File.expand_path(from)
|
28
|
+
to = File.expand_path(to)
|
29
|
+
target = File.join(to, File.basename(from))
|
30
|
+
|
31
|
+
unless File.exist?(target)
|
32
|
+
@logger.info "mv #{from.inspect} #{to.inspect}"
|
33
|
+
FileUtils.mv(from, to, @file_options)
|
34
|
+
else
|
35
|
+
@logger.warn "skipping #{from.inspect} because #{target.inspect} already exists"
|
36
|
+
end
|
28
37
|
end
|
29
38
|
end
|
30
39
|
|
31
40
|
# Move the given path to the trash (as set by <tt>trash_path</tt>).
|
32
41
|
#
|
33
42
|
# The path is moved if a file already exists in the trash with the same name. However, the current date and time is appended to the filename.
|
43
|
+
#
|
44
|
+
# Note: the OS native "restore" or "put back" functionality for trashed files is not currently supported. However, they can be restored manually, and the Maid log can help assist with this.
|
45
|
+
#
|
46
|
+
# Options:
|
47
|
+
#
|
48
|
+
# - :remove_over => Fixnum (e.g. 1.gigabyte, 1024.megabytes)
|
49
|
+
# Remove files over the given size rather than moving to the trash.
|
50
|
+
# See also Maid::NumericExtensions::SizeToKb
|
34
51
|
#
|
35
52
|
# trash('~/Downloads/foo.zip')
|
36
|
-
|
37
|
-
|
38
|
-
|
53
|
+
#
|
54
|
+
# This method can also handle multiple paths.
|
55
|
+
#
|
56
|
+
# trash(['~/Downloads/foo.zip', '~/Downloads/bar.zip'])
|
57
|
+
# trash(dir('~/Downloads/*.zip'))
|
58
|
+
def trash(paths, options = {})
|
59
|
+
# ## Implementation Notes
|
60
|
+
#
|
61
|
+
# Trashing files correctly is surprisingly hard. What Maid ends up doing is one the easiest, most foolproof solutions: moving the file.
|
62
|
+
#
|
63
|
+
# Unfortunately, that means it's not possile to restore files automatically in OSX or Ubuntu. The previous location of the file is lost.
|
64
|
+
#
|
65
|
+
# OSX support depends on AppleScript or would require a not-yet-written C extension to interface with the OS. The AppleScript solution is less than ideal: the user has to be logged in, Finder has to be running, and it makes the "trash can sound" every time a file is moved.
|
66
|
+
#
|
67
|
+
# Ubuntu makes it easy to implement, and there's a Python library for doing so (see `trash-cli`). However, there's not a Ruby equivalent yet.
|
39
68
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
69
|
+
Array(paths).each do |path|
|
70
|
+
target = File.join(@trash_path, File.basename(path))
|
71
|
+
safe_trash_path = File.join(@trash_path, "#{File.basename(path)} #{Time.now.strftime('%Y-%m-%d-%H-%M-%S')}")
|
72
|
+
|
73
|
+
if options[:remove_over] &&
|
74
|
+
File.exist?(path) &&
|
75
|
+
disk_usage(path) > options[:remove_over]
|
76
|
+
remove(path)
|
77
|
+
end
|
78
|
+
|
79
|
+
if File.exist?(path)
|
80
|
+
if File.exist?(target)
|
81
|
+
move(path, safe_trash_path)
|
82
|
+
else
|
83
|
+
move(path, @trash_path)
|
84
|
+
end
|
85
|
+
end
|
44
86
|
end
|
45
87
|
end
|
46
88
|
|
47
|
-
#
|
89
|
+
# Remove the given path recursively.
|
90
|
+
#
|
91
|
+
# Options:
|
48
92
|
#
|
49
|
-
#
|
93
|
+
# - :force => boolean
|
94
|
+
# - :secure => boolean (See FileUtils.remove_entry_secure for further details)
|
95
|
+
#
|
96
|
+
# remove('~/Downloads/foo.zip')
|
97
|
+
#
|
98
|
+
# This method can handle multiple remove paths.
|
99
|
+
#
|
100
|
+
# remove(['~/Downloads/foo.zip', '~/Downloads/bar.zip'])
|
101
|
+
# remove(dir('~/Downloads/*.zip'))
|
102
|
+
def remove(paths, options = {})
|
103
|
+
Array(paths).each do |path|
|
104
|
+
path = File.expand_path(path)
|
105
|
+
options = @file_options.merge(options)
|
106
|
+
|
107
|
+
@logger.info "Removing #{path.inspect}"
|
108
|
+
FileUtils.rm_r(path,options)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Give all files matching the given glob.
|
50
113
|
#
|
51
114
|
# dir('~/Downloads/*.zip')
|
52
115
|
def dir(glob)
|
53
116
|
Dir[File.expand_path(glob)]
|
54
117
|
end
|
55
118
|
|
119
|
+
# Creates a directory and all its parent directories.
|
120
|
+
#
|
121
|
+
# Options:
|
122
|
+
#
|
123
|
+
# - :mode, the symbolic and absolute mode both can be used.
|
124
|
+
# eg. 0700, 'u=wr,go=rr'
|
125
|
+
#
|
126
|
+
# mkdir('~/Downloads/Music/Pink.Floyd/', :mode => 0644)
|
127
|
+
def mkdir(path, options = {})
|
128
|
+
FileUtils.mkdir_p(File.expand_path(path), options)
|
129
|
+
end
|
130
|
+
|
56
131
|
# Find matching files, akin to the Unix utility <tt>find</tt>.
|
57
132
|
#
|
58
|
-
#
|
133
|
+
# If no block is given, it will return an array.
|
134
|
+
#
|
135
|
+
# find '~/Downloads/' # => [...]
|
136
|
+
#
|
137
|
+
# or delegates to Find.find.
|
59
138
|
#
|
60
139
|
# find '~/Downloads/' do |path|
|
61
140
|
# # ...
|
62
141
|
# end
|
142
|
+
#
|
63
143
|
def find(path, &block)
|
64
|
-
|
144
|
+
expanded_path = File.expand_path(path)
|
145
|
+
|
146
|
+
if block.nil?
|
147
|
+
files = []
|
148
|
+
Find.find(expanded_path) { |file_path| files << file_path }
|
149
|
+
files
|
150
|
+
else
|
151
|
+
Find.find(expanded_path, &block)
|
152
|
+
end
|
65
153
|
end
|
66
154
|
|
67
155
|
# [Mac OS X] Use Spotlight to locate all files matching the given filename.
|
@@ -99,27 +187,93 @@ module Maid::Tools
|
|
99
187
|
|
100
188
|
# Calculate disk usage of a given path.
|
101
189
|
#
|
190
|
+
# FIXME: This reports in kilobytes, but should probably report in bytes.
|
191
|
+
#
|
102
192
|
# disk_usage('foo.zip') # => 136
|
103
193
|
def disk_usage(path)
|
104
194
|
raw = cmd("du -s #{path.inspect}")
|
105
|
-
raw.split(/\s+/).first.to_i
|
195
|
+
usage_kb = raw.split(/\s+/).first.to_i
|
196
|
+
|
197
|
+
if usage_kb.zero?
|
198
|
+
raise "Stopping pessimistically because of unexpected value from du (#{raw.inspect})"
|
199
|
+
else
|
200
|
+
usage_kb
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
# In Unix speak, "ctime".
|
205
|
+
#
|
206
|
+
# created_at('foo.zip') # => Sat Apr 09 10:50:01 -0400 2011
|
207
|
+
def created_at(path)
|
208
|
+
File.ctime(File.expand_path(path))
|
106
209
|
end
|
107
210
|
|
108
211
|
# In Unix speak, "atime".
|
109
212
|
#
|
110
|
-
#
|
111
|
-
def
|
213
|
+
# accessed_at('foo.zip') # => Sat Apr 09 10:50:01 -0400 2011
|
214
|
+
def accessed_at(path)
|
112
215
|
File.atime(File.expand_path(path))
|
113
216
|
end
|
114
217
|
|
218
|
+
alias :last_accessed :accessed_at
|
219
|
+
deprecated :last_accessed, :accessed_at
|
220
|
+
|
221
|
+
# In Unix speak, "mtime".
|
222
|
+
#
|
223
|
+
# modified_at('foo.zip') # => Sat Apr 09 10:50:01 -0400 2011
|
224
|
+
def modified_at(path)
|
225
|
+
File.mtime(File.expand_path(path))
|
226
|
+
end
|
227
|
+
|
115
228
|
# Pulls and pushes the given git repository.
|
116
229
|
#
|
117
|
-
#
|
230
|
+
# Since this is deprecated, you might also be interested in SparkleShare (http://sparkleshare.org/), a great git-based file syncronization project.
|
118
231
|
#
|
119
232
|
# git_piston('~/code/projectname')
|
233
|
+
#
|
234
|
+
# @deprecated
|
120
235
|
def git_piston(path)
|
121
236
|
full_path = File.expand_path(path)
|
122
237
|
stdout = cmd("cd #{full_path.inspect} && git pull && git push 2>&1")
|
123
238
|
@logger.info "Fired git piston on #{full_path.inspect}. STDOUT:\n\n#{stdout}"
|
124
239
|
end
|
240
|
+
|
241
|
+
deprecated :git_piston, 'SparkleShare (http://sparkleshare.org/)'
|
242
|
+
|
243
|
+
# [Rsync] Simple sync of two files/folders using rsync.
|
244
|
+
#
|
245
|
+
# See rsync man page for a detailed description.
|
246
|
+
#
|
247
|
+
# Options:
|
248
|
+
#
|
249
|
+
# - :delete => boolean
|
250
|
+
# - :verbose => boolean
|
251
|
+
# - :archive => boolean (default true)
|
252
|
+
# - :update => boolean (default true)
|
253
|
+
# - :exclude => string EXE :exclude => ".git" or :exclude => [".git", ".rvmrc"]
|
254
|
+
# - :prune_empty => boolean
|
255
|
+
#
|
256
|
+
# sync('~/music', '/backup/music')
|
257
|
+
def sync(from, to, options = {})
|
258
|
+
# expand path removes trailing slash
|
259
|
+
# cannot use str[-1] due to ruby 1.8.7 restriction
|
260
|
+
from = File.expand_path(from) + (from.end_with?('/') ? '/' : '')
|
261
|
+
to = File.expand_path(to) + (to.end_with?('/') ? '/' : '')
|
262
|
+
# default options
|
263
|
+
options = { :archive => true, :update => true }.merge(options)
|
264
|
+
ops = []
|
265
|
+
ops << '-a' if options[:archive]
|
266
|
+
ops << '-v' if options[:verbose]
|
267
|
+
ops << '-u' if options[:update]
|
268
|
+
ops << '-m' if options[:prune_empty]
|
269
|
+
ops << '-n' if @file_options[:noop]
|
270
|
+
|
271
|
+
Array(options[:exclude]).each do |path|
|
272
|
+
ops << "--exclude=#{path.inspect}"
|
273
|
+
end
|
274
|
+
|
275
|
+
ops << '--delete' if options[:delete]
|
276
|
+
stdout = cmd("rsync #{ops.join(' ')} #{from.inspect} #{to.inspect} 2>&1")
|
277
|
+
@logger.info "Fired sync from #{from.inspect} to #{to.inspect}. STDOUT:\n\n#{stdout}"
|
278
|
+
end
|
125
279
|
end
|