maid 0.7.0.alpha.1 → 0.7.0.alpha.2

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog CHANGED
@@ -2,6 +2,8 @@ maid (0.7.0) unstable; urgency=low
2
2
 
3
3
  * Add dependencies: "exifr", "geocoder"
4
4
  * Add "location_city" tool
5
+ * Itsuki Kurokawa: Add "ignore_child_dirs" tool
6
+ * Itsuki Kurokawa: Add "tree_empty?" tool
5
7
 
6
8
  -- Benjamin Oakes <hello@benjaminoakes.com> TODO
7
9
 
data/lib/maid/tools.rb CHANGED
@@ -703,6 +703,57 @@ module Maid::Tools
703
703
  Array(paths).select { |p| !(filter_types & content_types(p)).empty? }
704
704
  end
705
705
 
706
+ # Test whether a directory is either empty, or contains only empty
707
+ # directories/subdirectories.
708
+ #
709
+ # ## Example
710
+ #
711
+ # if tree_empty? dir('~/Downloads/foo')
712
+ # trash '~/Downloads/foo'
713
+ # end
714
+ def tree_empty?(root)
715
+ return nil if File.file? root
716
+ return true if Dir.glob(root + '/*').length == 0
717
+
718
+ ignore = []
719
+
720
+ # Look for files.
721
+ return false if Dir.glob(root + '/*').select { |f| File.file? f }.length > 0
722
+
723
+ empty_dirs = Dir.glob(root + '/**/*').select { |d|
724
+ File.directory?(d)
725
+ }.reverse.select { |d|
726
+ # `.reverse` sorts deeper directories first.
727
+
728
+ # If the directory is empty, its parent should ignore it.
729
+ should_ignore = Dir.glob(d + '/*').select { |n|
730
+ not ignore.include? n
731
+ }.length == 0
732
+
733
+ ignore << d if should_ignore
734
+
735
+ should_ignore
736
+ }
737
+
738
+ Dir.glob(root + '/*').select { |n|
739
+ not empty_dirs.include? n
740
+ }.length == 0
741
+ end
742
+
743
+ # Given an array of directories, return a new array without any child
744
+ # directories whose parent is already present in that array.
745
+ #
746
+ # ## Example
747
+ #
748
+ # ignore_child_dirs(["foo", "foo/a", "foo/b", "bar"]) # => ["foo", "bar"]
749
+ def ignore_child_dirs(arr)
750
+ arr.sort { |x, y|
751
+ y.count('/') - x.count('/')
752
+ }.select { |d|
753
+ not arr.include?(File.dirname(d))
754
+ }
755
+ end
756
+
706
757
  private
707
758
 
708
759
  def firefox_downloading?(path)
data/lib/maid/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Maid
2
- VERSION = '0.7.0.alpha.1'
2
+ VERSION = '0.7.0.alpha.2'
3
3
  SUMMARY = 'Be lazy. Let Maid clean up after you, based on rules you define. Think of it as "Hazel for hackers".'
4
4
  end
@@ -698,5 +698,69 @@ module Maid
698
698
  end
699
699
  end
700
700
  end
701
+
702
+ describe '#tree_empty?' do
703
+ before do
704
+ @root = '~/Source'
705
+ @empty_dir = (@parent_of_empty_dir = @root + '/empty-parent') + '/empty'
706
+ @file = (@non_empty_dir = @root + '/non-empty') + '/file.txt'
707
+ FileUtils.mkdir_p(@empty_dir)
708
+ FileUtils.mkdir_p(@non_empty_dir)
709
+ FileUtils.touch(@file)
710
+ end
711
+
712
+ it 'returns false for non-empty directories' do
713
+ expect(@maid.tree_empty?(@non_empty_dir)).to be(false)
714
+ end
715
+
716
+ it 'returns true for empty directories' do
717
+ expect(@maid.tree_empty?(@empty_dir)).to be(true)
718
+ end
719
+
720
+ it 'returns true for directories with empty subdirectories' do
721
+ expect(@maid.tree_empty?(@parent_of_empty_dir)).to be(true)
722
+ end
723
+
724
+ it 'returns false for directories with non-empty subdirectories' do
725
+ expect(@maid.tree_empty?(@root)).to be(false)
726
+ end
727
+ end
728
+
729
+ describe '#ignore_child_dirs' do
730
+ it 'filters out any child directory' do
731
+ src = [
732
+ "a",
733
+ "b",
734
+ "b/x",
735
+ "c",
736
+ "c/x",
737
+ "c/y",
738
+ "d/x",
739
+ "d/y",
740
+ "e/x/y",
741
+ "e/x/y/z",
742
+ "f/x/y/z",
743
+ "g/x/y",
744
+ "g/x/z",
745
+ "g/y/a/b",
746
+ "g/y/a/c",
747
+ ]
748
+ expected = [
749
+ "a", # no child directories
750
+ "b", # ignore b/x
751
+ "c", # ignore c/x and c/y
752
+ "d/x", # no child directories
753
+ "d/y", # no child directories
754
+ "e/x/y", # ignore e/x/y/z
755
+ "f/x/y/z", # no empty parents
756
+ "g/x/y", # g/x isn't empty
757
+ "g/x/z",
758
+ "g/y/a/b", # g/y/a isn't empty
759
+ "g/y/a/c",
760
+ ].sort
761
+
762
+ expect(@maid.ignore_child_dirs(src).sort).to eq(expected)
763
+ end
764
+ end
701
765
  end
702
766
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0.alpha.1
4
+ version: 0.7.0.alpha.2
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-01-02 00:00:00.000000000 Z
12
+ date: 2015-03-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: escape
16
- requirement: &21482480 !ruby/object:Gem::Requirement
16
+ requirement: &15664940 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -24,10 +24,10 @@ dependencies:
24
24
  version: 0.1.0
25
25
  type: :runtime
26
26
  prerelease: false
27
- version_requirements: *21482480
27
+ version_requirements: *15664940
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: thor
30
- requirement: &21481740 !ruby/object:Gem::Requirement
30
+ requirement: &15662820 !ruby/object:Gem::Requirement
31
31
  none: false
32
32
  requirements:
33
33
  - - ! '>='
@@ -38,10 +38,10 @@ dependencies:
38
38
  version: 1.0.0
39
39
  type: :runtime
40
40
  prerelease: false
41
- version_requirements: *21481740
41
+ version_requirements: *15662820
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: deprecated
44
- requirement: &21481020 !ruby/object:Gem::Requirement
44
+ requirement: &15660640 !ruby/object:Gem::Requirement
45
45
  none: false
46
46
  requirements:
47
47
  - - ~>
@@ -49,10 +49,10 @@ dependencies:
49
49
  version: 3.0.0
50
50
  type: :runtime
51
51
  prerelease: false
52
- version_requirements: *21481020
52
+ version_requirements: *15660640
53
53
  - !ruby/object:Gem::Dependency
54
54
  name: dimensions
55
- requirement: &21480540 !ruby/object:Gem::Requirement
55
+ requirement: &15659060 !ruby/object:Gem::Requirement
56
56
  none: false
57
57
  requirements:
58
58
  - - ! '>='
@@ -63,10 +63,10 @@ dependencies:
63
63
  version: '2.0'
64
64
  type: :runtime
65
65
  prerelease: false
66
- version_requirements: *21480540
66
+ version_requirements: *15659060
67
67
  - !ruby/object:Gem::Dependency
68
68
  name: mime-types
69
- requirement: &21479820 !ruby/object:Gem::Requirement
69
+ requirement: &15671640 !ruby/object:Gem::Requirement
70
70
  none: false
71
71
  requirements:
72
72
  - - ~>
@@ -74,10 +74,10 @@ dependencies:
74
74
  version: '2.0'
75
75
  type: :runtime
76
76
  prerelease: false
77
- version_requirements: *21479820
77
+ version_requirements: *15671640
78
78
  - !ruby/object:Gem::Dependency
79
79
  name: rubyzip
80
- requirement: &21479360 !ruby/object:Gem::Requirement
80
+ requirement: &15669140 !ruby/object:Gem::Requirement
81
81
  none: false
82
82
  requirements:
83
83
  - - ~>
@@ -85,10 +85,10 @@ dependencies:
85
85
  version: 1.1.0
86
86
  type: :runtime
87
87
  prerelease: false
88
- version_requirements: *21479360
88
+ version_requirements: *15669140
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: xdg
91
- requirement: &21478900 !ruby/object:Gem::Requirement
91
+ requirement: &15682880 !ruby/object:Gem::Requirement
92
92
  none: false
93
93
  requirements:
94
94
  - - ~>
@@ -96,10 +96,10 @@ dependencies:
96
96
  version: 2.2.3
97
97
  type: :runtime
98
98
  prerelease: false
99
- version_requirements: *21478900
99
+ version_requirements: *15682880
100
100
  - !ruby/object:Gem::Dependency
101
101
  name: listen
102
- requirement: &20897480 !ruby/object:Gem::Requirement
102
+ requirement: &15680240 !ruby/object:Gem::Requirement
103
103
  none: false
104
104
  requirements:
105
105
  - - ~>
@@ -107,10 +107,10 @@ dependencies:
107
107
  version: 2.8.0
108
108
  type: :runtime
109
109
  prerelease: false
110
- version_requirements: *20897480
110
+ version_requirements: *15680240
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rufus-scheduler
113
- requirement: &20895860 !ruby/object:Gem::Requirement
113
+ requirement: &15690200 !ruby/object:Gem::Requirement
114
114
  none: false
115
115
  requirements:
116
116
  - - ~>
@@ -118,10 +118,10 @@ dependencies:
118
118
  version: 3.0.6
119
119
  type: :runtime
120
120
  prerelease: false
121
- version_requirements: *20895860
121
+ version_requirements: *15690200
122
122
  - !ruby/object:Gem::Dependency
123
123
  name: exifr
124
- requirement: &20894420 !ruby/object:Gem::Requirement
124
+ requirement: &15688820 !ruby/object:Gem::Requirement
125
125
  none: false
126
126
  requirements:
127
127
  - - ~>
@@ -129,10 +129,10 @@ dependencies:
129
129
  version: 1.2.0
130
130
  type: :runtime
131
131
  prerelease: false
132
- version_requirements: *20894420
132
+ version_requirements: *15688820
133
133
  - !ruby/object:Gem::Dependency
134
134
  name: geocoder
135
- requirement: &20192760 !ruby/object:Gem::Requirement
135
+ requirement: &15688100 !ruby/object:Gem::Requirement
136
136
  none: false
137
137
  requirements:
138
138
  - - ~>
@@ -140,10 +140,10 @@ dependencies:
140
140
  version: 1.2.0
141
141
  type: :runtime
142
142
  prerelease: false
143
- version_requirements: *20192760
143
+ version_requirements: *15688100
144
144
  - !ruby/object:Gem::Dependency
145
145
  name: fakefs
146
- requirement: &20192300 !ruby/object:Gem::Requirement
146
+ requirement: &15687040 !ruby/object:Gem::Requirement
147
147
  none: false
148
148
  requirements:
149
149
  - - ~>
@@ -151,10 +151,10 @@ dependencies:
151
151
  version: 0.4.2
152
152
  type: :development
153
153
  prerelease: false
154
- version_requirements: *20192300
154
+ version_requirements: *15687040
155
155
  - !ruby/object:Gem::Dependency
156
156
  name: guard
157
- requirement: &20191840 !ruby/object:Gem::Requirement
157
+ requirement: &15719380 !ruby/object:Gem::Requirement
158
158
  none: false
159
159
  requirements:
160
160
  - - ~>
@@ -162,10 +162,10 @@ dependencies:
162
162
  version: 2.10.4
163
163
  type: :development
164
164
  prerelease: false
165
- version_requirements: *20191840
165
+ version_requirements: *15719380
166
166
  - !ruby/object:Gem::Dependency
167
167
  name: guard-rspec
168
- requirement: &20191380 !ruby/object:Gem::Requirement
168
+ requirement: &15715640 !ruby/object:Gem::Requirement
169
169
  none: false
170
170
  requirements:
171
171
  - - ~>
@@ -173,10 +173,10 @@ dependencies:
173
173
  version: 4.5.0
174
174
  type: :development
175
175
  prerelease: false
176
- version_requirements: *20191380
176
+ version_requirements: *15715640
177
177
  - !ruby/object:Gem::Dependency
178
178
  name: rake
179
- requirement: &20190920 !ruby/object:Gem::Requirement
179
+ requirement: &15714700 !ruby/object:Gem::Requirement
180
180
  none: false
181
181
  requirements:
182
182
  - - ~>
@@ -184,10 +184,10 @@ dependencies:
184
184
  version: 10.4.2
185
185
  type: :development
186
186
  prerelease: false
187
- version_requirements: *20190920
187
+ version_requirements: *15714700
188
188
  - !ruby/object:Gem::Dependency
189
189
  name: redcarpet
190
- requirement: &20190460 !ruby/object:Gem::Requirement
190
+ requirement: &15712460 !ruby/object:Gem::Requirement
191
191
  none: false
192
192
  requirements:
193
193
  - - ~>
@@ -195,10 +195,10 @@ dependencies:
195
195
  version: 3.2.2
196
196
  type: :development
197
197
  prerelease: false
198
- version_requirements: *20190460
198
+ version_requirements: *15712460
199
199
  - !ruby/object:Gem::Dependency
200
200
  name: rspec
201
- requirement: &20190000 !ruby/object:Gem::Requirement
201
+ requirement: &15726780 !ruby/object:Gem::Requirement
202
202
  none: false
203
203
  requirements:
204
204
  - - ~>
@@ -206,10 +206,10 @@ dependencies:
206
206
  version: 3.1.0
207
207
  type: :development
208
208
  prerelease: false
209
- version_requirements: *20190000
209
+ version_requirements: *15726780
210
210
  - !ruby/object:Gem::Dependency
211
211
  name: timecop
212
- requirement: &20189540 !ruby/object:Gem::Requirement
212
+ requirement: &15722640 !ruby/object:Gem::Requirement
213
213
  none: false
214
214
  requirements:
215
215
  - - ~>
@@ -217,10 +217,10 @@ dependencies:
217
217
  version: 0.7.0
218
218
  type: :development
219
219
  prerelease: false
220
- version_requirements: *20189540
220
+ version_requirements: *15722640
221
221
  - !ruby/object:Gem::Dependency
222
222
  name: yard
223
- requirement: &20189080 !ruby/object:Gem::Requirement
223
+ requirement: &15720520 !ruby/object:Gem::Requirement
224
224
  none: false
225
225
  requirements:
226
226
  - - ~>
@@ -228,10 +228,10 @@ dependencies:
228
228
  version: 0.8.4
229
229
  type: :development
230
230
  prerelease: false
231
- version_requirements: *20189080
231
+ version_requirements: *15720520
232
232
  - !ruby/object:Gem::Dependency
233
233
  name: rb-inotify
234
- requirement: &20188620 !ruby/object:Gem::Requirement
234
+ requirement: &15719640 !ruby/object:Gem::Requirement
235
235
  none: false
236
236
  requirements:
237
237
  - - ~>
@@ -239,10 +239,10 @@ dependencies:
239
239
  version: 0.9.0
240
240
  type: :development
241
241
  prerelease: false
242
- version_requirements: *20188620
242
+ version_requirements: *15719640
243
243
  - !ruby/object:Gem::Dependency
244
244
  name: rb-fsevent
245
- requirement: &20188160 !ruby/object:Gem::Requirement
245
+ requirement: &15735180 !ruby/object:Gem::Requirement
246
246
  none: false
247
247
  requirements:
248
248
  - - ~>
@@ -250,7 +250,7 @@ dependencies:
250
250
  version: 0.9.2
251
251
  type: :development
252
252
  prerelease: false
253
- version_requirements: *20188160
253
+ version_requirements: *15735180
254
254
  description: Be lazy. Let Maid clean up after you, based on rules you define. Think
255
255
  of it as "Hazel for hackers".
256
256
  email:
@@ -308,7 +308,7 @@ files:
308
308
  - spec/fixtures/files/ruby.jpg
309
309
  - spec/fixtures/files/sydney.jpg
310
310
  - spec/fixtures/files/unknown.foo
311
- - ! "spec/fixtures/files/ã\x81\x95.zip"
311
+ - spec/fixtures/files/さ.zip
312
312
  - spec/lib/maid/app_spec.rb
313
313
  - spec/lib/maid/maid_spec.rb
314
314
  - spec/lib/maid/numeric_extensions_spec.rb