maid 0.8.0.alpha.3 → 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 +13 -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 +19 -18
- 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 +205 -126
- data/.travis.yml +0 -15
data/spec/lib/maid/tools_spec.rb
CHANGED
@@ -1,28 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
|
-
# Workaround for Ruby 2.1.0, remove after https://github.com/defunkt/fakefs/pull/209 is released
|
5
|
-
if RUBY_VERSION =~ /2\.[12]\.\d/
|
6
|
-
module FakeFS
|
7
|
-
class Dir
|
8
|
-
def self.entries(dirname, opts = {})
|
9
|
-
_check_for_valid_file(dirname)
|
10
|
-
|
11
|
-
Dir.new(dirname).map { |file| File.basename(file) }
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
# Workaround for broken `cp` implementation; remove after upgrading FakeFS
|
18
|
-
module FakeFS
|
19
|
-
module FileUtils
|
20
|
-
def self.cp(src, dest, options = {})
|
21
|
-
copy(src, dest)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
4
|
module Maid
|
27
5
|
# NOTE: Please use FakeFS instead of mocking and stubbing specific calls which happen to modify the filesystem.
|
28
6
|
#
|
@@ -48,15 +26,20 @@ module Maid
|
|
48
26
|
|
49
27
|
describe '#move' do
|
50
28
|
before do
|
51
|
-
@
|
52
|
-
|
53
|
-
|
54
|
-
|
29
|
+
@src_dir = File.join('~', 'Source')
|
30
|
+
@file_name = 'foo.zip'
|
31
|
+
@src_file = File.join(@src_dir, @file_name)
|
32
|
+
@dst_dir = File.join('~', 'Destination')
|
33
|
+
FileUtils.mkdir_p(File.expand_path(@src_dir))
|
34
|
+
FileUtils.touch(File.expand_path(@src_file))
|
35
|
+
FileUtils.mkdir_p(File.expand_path(@dst_dir))
|
55
36
|
end
|
56
37
|
|
57
38
|
it 'moves expanded paths, passing file_options' do
|
39
|
+
dest_file = File.expand_path(File.join(@dst_dir, @file_name))
|
40
|
+
|
58
41
|
@maid.move(@src_file, @dst_dir)
|
59
|
-
expect(File.
|
42
|
+
expect(File.exist?(dest_file)).to be(true)
|
60
43
|
end
|
61
44
|
|
62
45
|
it 'logs the move' do
|
@@ -65,18 +48,21 @@ module Maid
|
|
65
48
|
end
|
66
49
|
|
67
50
|
it 'handles multiple from paths' do
|
68
|
-
|
69
|
-
|
51
|
+
second_file_name = 'bar.zip'
|
52
|
+
second_src_file = File.join(@src_dir, second_file_name)
|
53
|
+
FileUtils.touch(File.expand_path(second_src_file))
|
70
54
|
src_files = [@src_file, second_src_file]
|
55
|
+
dst_file = File.expand_path(File.join(@dst_dir, @file_name))
|
56
|
+
second_dst_file = File.expand_path(File.join(@dst_dir, second_file_name))
|
71
57
|
|
72
58
|
@maid.move(src_files, @dst_dir)
|
73
|
-
expect(File.exist?(
|
74
|
-
expect(File.exist?(
|
59
|
+
expect(File.exist?(dst_file)).to be(true)
|
60
|
+
expect(File.exist?(second_dst_file)).to be(true)
|
75
61
|
end
|
76
62
|
|
77
63
|
context 'given the destination directory does not exist' do
|
78
64
|
before do
|
79
|
-
FileUtils.rmdir(@dst_dir)
|
65
|
+
FileUtils.rmdir(File.expand_path(@dst_dir))
|
80
66
|
end
|
81
67
|
|
82
68
|
it 'does not overwrite when moving' do
|
@@ -92,8 +78,8 @@ module Maid
|
|
92
78
|
describe '#rename' do
|
93
79
|
before do
|
94
80
|
@src_file = (@src_dir = '~/Source/') + (@file_name = 'foo.zip')
|
95
|
-
FileUtils.mkdir_p(@src_dir)
|
96
|
-
FileUtils.touch(@src_file)
|
81
|
+
FileUtils.mkdir_p(File.expand_path(@src_dir))
|
82
|
+
FileUtils.touch(File.expand_path(@src_file))
|
97
83
|
@expanded_src_name = "#@home/Source/foo.zip"
|
98
84
|
|
99
85
|
@dst_name = '~/Destination/bar.zip'
|
@@ -108,11 +94,11 @@ module Maid
|
|
108
94
|
end
|
109
95
|
|
110
96
|
it 'moves the file from the source to the destination' do
|
111
|
-
expect(File.
|
112
|
-
expect(File.
|
97
|
+
expect(File.exist?(@expanded_src_name)).to be(true)
|
98
|
+
expect(File.exist?(@expanded_dst_name)).to be(false)
|
113
99
|
@maid.rename(@src_file, @dst_name)
|
114
|
-
expect(File.
|
115
|
-
expect(File.
|
100
|
+
expect(File.exist?(@expanded_src_name)).to be(false)
|
101
|
+
expect(File.exist?(@expanded_dst_name)).to be(true)
|
116
102
|
end
|
117
103
|
|
118
104
|
context 'given the target already exists' do
|
@@ -132,9 +118,11 @@ module Maid
|
|
132
118
|
describe '#trash' do
|
133
119
|
before do
|
134
120
|
@trash_path = @maid.trash_path
|
135
|
-
@
|
136
|
-
|
137
|
-
|
121
|
+
@src_dir = File.join('~', 'Source/')
|
122
|
+
@file_name = 'foo.zip'
|
123
|
+
@src_file = File.join(@src_dir, @file_name)
|
124
|
+
FileUtils.mkdir_p(File.expand_path(@src_dir))
|
125
|
+
FileUtils.touch(File.expand_path(@src_file))
|
138
126
|
|
139
127
|
@trash_file = File.join(@trash_path, @file_name)
|
140
128
|
end
|
@@ -155,12 +143,14 @@ module Maid
|
|
155
143
|
end
|
156
144
|
|
157
145
|
it 'handles multiple paths' do
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
@
|
162
|
-
|
146
|
+
second_file_name = 'bar.zip'
|
147
|
+
second_src_file = File.join(@src_dir, second_file_name)
|
148
|
+
FileUtils.touch(File.expand_path(second_src_file))
|
149
|
+
src_files = [@src_file, second_src_file]
|
163
150
|
second_trash_file = File.join(@trash_path, second_file_name)
|
151
|
+
|
152
|
+
@maid.trash(src_files)
|
153
|
+
|
164
154
|
expect(File.exist?(@trash_file)).to be(true)
|
165
155
|
expect(File.exist?(second_trash_file)).to be(true)
|
166
156
|
end
|
@@ -181,11 +171,11 @@ module Maid
|
|
181
171
|
|
182
172
|
describe '#remove' do
|
183
173
|
before do
|
184
|
-
@
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
@
|
174
|
+
@src_dir = File.join('~', 'Source')
|
175
|
+
@file_name = 'foo.zip'
|
176
|
+
@src_file = File.join(@src_dir, @file_name)
|
177
|
+
FileUtils.mkdir_p(File.expand_path(@src_dir))
|
178
|
+
FileUtils.touch(File.expand_path(@src_file))
|
189
179
|
end
|
190
180
|
|
191
181
|
it 'removes expanded paths, passing options' do
|
@@ -199,25 +189,25 @@ module Maid
|
|
199
189
|
end
|
200
190
|
|
201
191
|
it 'sets the secure option' do
|
202
|
-
@options = @
|
203
|
-
expect(FileUtils).to receive(:rm_r).with(@
|
192
|
+
@options = @maid.file_options.merge(:secure => true)
|
193
|
+
expect(FileUtils).to receive(:rm_r).with(File.expand_path(@src_file), @options)
|
204
194
|
@maid.remove(@src_file, :secure => true)
|
205
195
|
end
|
206
196
|
|
207
197
|
it 'sets the force option' do
|
208
|
-
@options = @
|
209
|
-
expect(FileUtils).to receive(:rm_r).with(@
|
198
|
+
@options = @maid.file_options.merge(:force => true)
|
199
|
+
expect(FileUtils).to receive(:rm_r).with(File.expand_path(@src_file), @options)
|
210
200
|
@maid.remove(@src_file, :force => true)
|
211
201
|
end
|
212
202
|
|
213
203
|
it 'handles multiple paths' do
|
214
|
-
second_src_file =
|
215
|
-
FileUtils.touch(second_src_file)
|
204
|
+
second_src_file = File.join(@src_dir, 'bar.zip')
|
205
|
+
FileUtils.touch(File.expand_path(second_src_file))
|
216
206
|
@src_files = [@src_file, second_src_file]
|
217
207
|
|
218
208
|
@maid.remove(@src_files)
|
219
|
-
expect(File.exist?(@src_file)).to be(false)
|
220
|
-
expect(File.exist?(second_src_file)).to be(false)
|
209
|
+
expect(File.exist?(File.expand_path(@src_file))).to be(false)
|
210
|
+
expect(File.exist?(File.expand_path(second_src_file))).to be(false)
|
221
211
|
end
|
222
212
|
end
|
223
213
|
|
@@ -354,9 +344,11 @@ module Maid
|
|
354
344
|
|
355
345
|
describe '#find' do
|
356
346
|
before do
|
357
|
-
@
|
358
|
-
|
359
|
-
|
347
|
+
@dir = File.join('~', 'Source')
|
348
|
+
@file_name = 'foo.zip'
|
349
|
+
@file = File.join(@dir, @file_name)
|
350
|
+
FileUtils.mkdir_p(File.expand_path(@dir))
|
351
|
+
FileUtils.touch(File.expand_path(@file))
|
360
352
|
@dir_expand_path = File.expand_path(@dir)
|
361
353
|
@file_expand_path = File.expand_path(@file)
|
362
354
|
end
|
@@ -467,13 +459,13 @@ module Maid
|
|
467
459
|
|
468
460
|
describe '#modified_at' do
|
469
461
|
before do
|
470
|
-
@path = '
|
462
|
+
@path = File.join('~', 'test.txt')
|
471
463
|
FileUtils.touch(File.expand_path(@path))
|
472
464
|
end
|
473
465
|
|
474
466
|
it 'gives the modified time of the file' do
|
475
467
|
Timecop.freeze(@now) do
|
476
|
-
File.open(@path, 'w') { |f| f.write('Test') }
|
468
|
+
File.open(File.expand_path(@path), 'w') { |f| f.write('Test') }
|
477
469
|
end
|
478
470
|
|
479
471
|
# use to_i to ignore milliseconds during test
|
@@ -548,46 +540,68 @@ module Maid
|
|
548
540
|
@maid.sync(@src_dir, @dst_dir, :exclude => ['.git', '.rvmrc'])
|
549
541
|
end
|
550
542
|
|
551
|
-
|
552
|
-
@maid.file_options
|
553
|
-
|
554
|
-
|
543
|
+
context 'when file_options[:noop] is true' do
|
544
|
+
let!(:original_file_options) { @maid.file_options.clone }
|
545
|
+
|
546
|
+
before do
|
547
|
+
@maid.file_options[:noop] = true
|
548
|
+
end
|
549
|
+
|
550
|
+
after do
|
551
|
+
@maid.file_options[:noop] = original_file_options[:noop]
|
552
|
+
end
|
553
|
+
|
554
|
+
it 'adds noop option' do
|
555
|
+
expect(@maid).to receive(:cmd).with(%(rsync -a -u -n #@home/Downloads/ #@home/Reference 2>&1))
|
556
|
+
@maid.sync(@src_dir, @dst_dir)
|
557
|
+
end
|
555
558
|
end
|
556
559
|
end
|
557
560
|
|
558
561
|
describe '#copy' do
|
562
|
+
let(:src_file) { File.join('~', 'Source', 'foo.zip') }
|
563
|
+
let(:src_dir) { File.dirname(src_file) }
|
564
|
+
let(:dst_file) { File.join('~', 'Destination', 'foo.zip') }
|
565
|
+
let(:dst_dir) { File.dirname(dst_file) }
|
566
|
+
|
559
567
|
before do
|
560
|
-
|
561
|
-
FileUtils.
|
562
|
-
FileUtils.
|
563
|
-
FileUtils.mkdir_p(@dst_dir = '~/Destination/')
|
568
|
+
FileUtils.mkdir_p(File.expand_path(src_dir))
|
569
|
+
FileUtils.touch(File.expand_path(src_file))
|
570
|
+
FileUtils.mkdir_p(File.expand_path(dst_dir))
|
564
571
|
end
|
565
572
|
|
566
573
|
it 'copies expanded paths, passing file_options' do
|
567
|
-
@maid.copy(
|
568
|
-
expect(File.
|
574
|
+
@maid.copy(src_file, dst_dir)
|
575
|
+
expect(File.exist?(File.expand_path(dst_file))).to be_truthy
|
569
576
|
end
|
570
577
|
|
571
578
|
it 'logs the copy' do
|
572
579
|
expect(@logger).to receive(:info)
|
573
|
-
@maid.copy(
|
580
|
+
@maid.copy(src_file, dst_dir)
|
574
581
|
end
|
575
582
|
|
576
583
|
it 'does not copy if the target already exists' do
|
577
|
-
FileUtils.touch(
|
584
|
+
FileUtils.touch(File.expand_path(dst_file))
|
578
585
|
expect(@logger).to receive(:warn)
|
579
586
|
|
580
|
-
@maid.copy(
|
587
|
+
@maid.copy(src_file, dst_dir)
|
581
588
|
end
|
582
589
|
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
src_files
|
590
|
+
context 'with multiple `from` paths' do
|
591
|
+
let(:first_file) { File.join(src_dir, 'bar.zip') }
|
592
|
+
let(:second_file) { File.join(src_dir, 'baz.zip') }
|
593
|
+
let(:src_files) { [first_file, second_file] }
|
587
594
|
|
588
|
-
|
589
|
-
|
590
|
-
|
595
|
+
before do
|
596
|
+
src_files.each { |file| FileUtils.touch(File.expand_path(file)) }
|
597
|
+
end
|
598
|
+
|
599
|
+
it 'copies all files' do
|
600
|
+
@maid.copy(src_files, dst_dir)
|
601
|
+
|
602
|
+
expect(File.exist?(File.expand_path(first_file))).to be_truthy
|
603
|
+
expect(File.exist?(File.expand_path(second_file))).to be_truthy
|
604
|
+
end
|
591
605
|
end
|
592
606
|
end
|
593
607
|
end
|
@@ -774,35 +788,39 @@ module Maid
|
|
774
788
|
end
|
775
789
|
|
776
790
|
describe 'OSX tag support', :fakefs => false do
|
791
|
+
let(:test_file) { '~/.maid/test/tag.zip' }
|
792
|
+
let(:test_dir) { File.dirname(test_file) }
|
793
|
+
let(:file_name) { File.basename(test_file) }
|
794
|
+
let(:original_file_options) { @maid.file_options.clone }
|
795
|
+
|
777
796
|
before do
|
778
797
|
@logger = double('Logger').as_null_object
|
779
798
|
@maid = Maid.new(:logger => @logger)
|
780
799
|
|
781
|
-
|
782
|
-
FileUtils.
|
783
|
-
FileUtils.touch(@test_file)
|
800
|
+
FileUtils.mkdir_p(test_dir)
|
801
|
+
FileUtils.touch(test_file)
|
784
802
|
@maid.file_options[:noop] = false
|
785
803
|
end
|
786
804
|
|
787
805
|
after do
|
788
|
-
FileUtils.rm_r(
|
789
|
-
@maid.file_options[:noop] =
|
806
|
+
FileUtils.rm_r(test_dir)
|
807
|
+
@maid.file_options[:noop] = original_file_options[:noop]
|
790
808
|
end
|
791
809
|
|
792
810
|
describe '#tags' do
|
793
811
|
it 'returns tags from a file that has one' do
|
794
812
|
if Platform.has_tag_available?
|
795
813
|
@maid.file_options[:noop] = false
|
796
|
-
@maid.add_tag(
|
797
|
-
expect(@maid.tags(
|
814
|
+
@maid.add_tag(test_file, "Test")
|
815
|
+
expect(@maid.tags(test_file)).to eq(["Test"])
|
798
816
|
end
|
799
817
|
end
|
800
818
|
|
801
819
|
it 'returns tags from a file that has serveral tags' do
|
802
820
|
if Platform.has_tag_available?
|
803
821
|
@maid.file_options[:noop] = false
|
804
|
-
@maid.add_tag(
|
805
|
-
expect(@maid.tags(
|
822
|
+
@maid.add_tag(test_file, ["Test", "Twice"])
|
823
|
+
expect(@maid.tags(test_file)).to eq(["Test", "Twice"])
|
806
824
|
end
|
807
825
|
end
|
808
826
|
end
|
@@ -810,22 +828,22 @@ module Maid
|
|
810
828
|
describe '#has_tags?' do
|
811
829
|
it 'returns true for a file with tags' do
|
812
830
|
if Platform.has_tag_available?
|
813
|
-
@maid.add_tag(
|
814
|
-
expect(@maid.has_tags?(
|
831
|
+
@maid.add_tag(test_file, "Test")
|
832
|
+
expect(@maid.has_tags?(test_file)).to be(true)
|
815
833
|
end
|
816
834
|
end
|
817
835
|
|
818
836
|
it 'returns false for a file without tags' do
|
819
|
-
expect(@maid.has_tags?(
|
837
|
+
expect(@maid.has_tags?(test_file)).to be(false)
|
820
838
|
end
|
821
839
|
end
|
822
840
|
|
823
841
|
describe '#contains_tag?' do
|
824
842
|
it 'returns true a file with the given tag' do
|
825
843
|
if Platform.has_tag_available?
|
826
|
-
@maid.add_tag(
|
827
|
-
expect(@maid.contains_tag?(
|
828
|
-
expect(@maid.contains_tag?(
|
844
|
+
@maid.add_tag(test_file, "Test")
|
845
|
+
expect(@maid.contains_tag?(test_file, "Test")).to be(true)
|
846
|
+
expect(@maid.contains_tag?(test_file, "Not there")).to be(false)
|
829
847
|
end
|
830
848
|
end
|
831
849
|
end
|
@@ -833,8 +851,8 @@ module Maid
|
|
833
851
|
describe '#add_tag' do
|
834
852
|
it 'adds the given tag to a file' do
|
835
853
|
if Platform.has_tag_available?
|
836
|
-
@maid.add_tag(
|
837
|
-
expect(@maid.contains_tag?(
|
854
|
+
@maid.add_tag(test_file, "Test")
|
855
|
+
expect(@maid.contains_tag?(test_file, "Test")).to be(true)
|
838
856
|
end
|
839
857
|
end
|
840
858
|
end
|
@@ -842,10 +860,10 @@ module Maid
|
|
842
860
|
describe '#remove_tag' do
|
843
861
|
it 'removes the given tag from a file' do
|
844
862
|
if Platform.has_tag_available?
|
845
|
-
@maid.add_tag(
|
846
|
-
expect(@maid.contains_tag?(
|
847
|
-
@maid.remove_tag(
|
848
|
-
expect(@maid.contains_tag?(
|
863
|
+
@maid.add_tag(test_file, "Test")
|
864
|
+
expect(@maid.contains_tag?(test_file, "Test")).to be(true)
|
865
|
+
@maid.remove_tag(test_file, "Test")
|
866
|
+
expect(@maid.contains_tag?(test_file, "Test")).to be(false)
|
849
867
|
end
|
850
868
|
end
|
851
869
|
end
|
@@ -853,11 +871,11 @@ module Maid
|
|
853
871
|
describe '#set_tag' do
|
854
872
|
it 'sets the given tags on a file' do
|
855
873
|
if Platform.has_tag_available?
|
856
|
-
@maid.set_tag(
|
857
|
-
expect(@maid.contains_tag?(
|
858
|
-
@maid.set_tag(
|
859
|
-
expect(@maid.contains_tag?(
|
860
|
-
expect(@maid.contains_tag?(
|
874
|
+
@maid.set_tag(test_file, "Test")
|
875
|
+
expect(@maid.contains_tag?(test_file, "Test")).to be(true)
|
876
|
+
@maid.set_tag(test_file, ["Test", "Twice"])
|
877
|
+
expect(@maid.contains_tag?(test_file, "Test")).to be(true)
|
878
|
+
expect(@maid.contains_tag?(test_file, "Twice")).to be(true)
|
861
879
|
end
|
862
880
|
end
|
863
881
|
end
|
@@ -51,25 +51,31 @@ module Maid
|
|
51
51
|
Logger.stub(:new) { double('Logger').as_null_object }
|
52
52
|
end
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
|
54
|
+
context 'in Linux' do
|
55
|
+
let(:filename) { 'foo.txt' }
|
56
|
+
let(:trash_contents) { Dir.glob(File.join(subject.correct_trash, '*'),
|
57
|
+
File::FNM_DOTMATCH) }
|
57
58
|
|
58
|
-
|
59
|
-
|
60
|
-
|
59
|
+
before do
|
60
|
+
subject.stub(:correct_trash) { File.expand_path('~/.local/share/Trash/files/') }
|
61
|
+
|
62
|
+
FileUtils.mkdir_p(subject.incorrect_trash)
|
63
|
+
FileUtils.touch(File.join(subject.incorrect_trash, filename))
|
64
|
+
FileUtils.mkdir_p(subject.correct_trash)
|
61
65
|
|
62
|
-
|
63
|
-
|
66
|
+
subject.perform
|
67
|
+
end
|
64
68
|
|
65
|
-
subject.perform
|
66
69
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
70
|
+
it 'removes all files from incorrect trash directory' do
|
71
|
+
expect(File.exist?(subject.incorrect_trash)).to be false
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'moves all files to the correct trash directory' do
|
75
|
+
expect(trash_contents.length).to eq(2)
|
76
|
+
expect(trash_contents[0]).to match(/files\/\.Trash$/)
|
77
|
+
expect(trash_contents[1]).to match(/files\/foo.txt$/)
|
78
|
+
end
|
73
79
|
end
|
74
80
|
end
|
75
81
|
end
|