clean_files 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 37dff8ca32b3bb5589f6da10f5f432b6ee451915
4
- data.tar.gz: 440c67a524f989b7fda79b8f476eac4e4351cf74
3
+ metadata.gz: c64267955da36b6816003e6e589ff0d14225e8ba
4
+ data.tar.gz: e57e92355da67ce51b39f4c7df3131d99d3c7191
5
5
  SHA512:
6
- metadata.gz: e50503dc029b2af56a3b94d713b767c41859b42176e91c97ba2e5a924e60a513a1dbfc5e54395e2bcb3be8733f84770b40d082623cf6f76b6239fa172cbe5fcb
7
- data.tar.gz: 7a85cdae3fdbd4a1c5d135a8b5cb1932726524fb4479c23a43ec5ce31d0df3bd89fc370dbf2d84314c64055f1eca8a1078c251e15635158c1d39992ccc50a5ae
6
+ metadata.gz: b527857e49d5497b7d5ea76f9e2574f9fbd0caaa2ea86d5b9ec64a0c4f8822f7457ed099ffcdd22e5f9ee9ffeafef285bd8b87ad2fa491d94f68c1c189ad41b5
7
+ data.tar.gz: b999c2eb25042e65f4fc7a0b1f582b478360c7d21c29f4d8893edea2a789dcf971f07d59adfec976a59b066d07355488219103d87658a7215b7f1e78c4395be1
data/bin/clean_files CHANGED
@@ -1,6 +1,6 @@
1
- #!/usr/bin/env ruby
1
+ #!/usr/bin/env ruby
2
2
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '/../lib'))
3
- require 'clean_files'
3
+ require 'clean_files/runner'
4
4
 
5
- app = CleanFiles.new(ARGV)
5
+ app = CleanFiles::Runner.new(ARGV)
6
6
  app.run
Binary file
data/clean_files.gemspec CHANGED
@@ -2,21 +2,23 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "clean_files"
5
- s.version = "1.0.1"
5
+ s.version = "1.1.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Tor Erik Linnerud"]
9
- s.date = %q{2009-05-05}
10
- s.default_executable = %q{clean_files}
11
- s.email = %q{torerik.linnerud@alphasights.com}
9
+ s.date = "2009-05-05"
10
+ s.default_executable = "clean_files"
11
+ s.email = "torerik.linnerud@alphasights.com"
12
12
  s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
13
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
14
14
  s.files = `git ls-files`.split($/)
15
15
  s.has_rdoc = true
16
- s.homepage = %q{http://github.com/alphasights/clean-files}
16
+ s.homepage = "http://github.com/alphasights/clean_files"
17
17
  s.require_paths = ["lib"]
18
- s.summary = %q{Executable to delete files which fit certain criteria}
18
+ s.summary = "Executable to delete files which fit certain criteria"
19
+ s.description = "Executable to delete files which fit certain criteria e.g. you can delete files older than 1 month keeping one weekly file"
19
20
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
21
+ s.license = 'MIT'
20
22
 
21
23
  s.add_dependency 'rake'
22
24
  s.add_dependency 'rspec'
@@ -0,0 +1,69 @@
1
+ require 'active_support/core_ext'
2
+
3
+ module CleanFiles
4
+ class Cleaner
5
+ attr_reader :paths, :options
6
+
7
+ VALID_OPTIONS = [:threshold, :pretend, :verbose, :recursive]
8
+ VALID_INTERVALS = [:hourly, :daily, :weekly, :monthly, :yearly]
9
+ TIME_INTERVALS = [:hour, :day, :cweek, :month, :year]
10
+
11
+ SimpleFile = Struct.new(:path, :stat) do
12
+ delegate :ctime, :file?, :directory?, :to => :stat
13
+ end
14
+
15
+ def initialize(paths, options = {})
16
+ @paths = [paths].flatten
17
+ @options = options.reverse_merge(:threshold => 30.days.ago)
18
+ options.assert_valid_keys(VALID_OPTIONS + VALID_INTERVALS)
19
+ given_intervals = VALID_INTERVALS & options.keys
20
+ if given_intervals.present?
21
+ lowest_selected_position = VALID_INTERVALS.index(given_intervals.first)
22
+ @key_intervals = TIME_INTERVALS[lowest_selected_position..-1]
23
+ end
24
+ end
25
+
26
+ def start
27
+ files = files_to_delete.map(&:path)
28
+ puts files.join("\n") if options[:verbose]
29
+ FileUtils.rm_rf(files, :noop => !!options[:pretend])
30
+ end
31
+
32
+ def files
33
+ if paths.any?{|path| path.include?('*')}
34
+ paths.map!{|path| Dir.glob(path)}
35
+ paths.flatten!
36
+ end
37
+ @_files ||= paths.map do |file_path|
38
+ begin
39
+ SimpleFile.new(file_path, File.stat(file_path))
40
+ rescue Errno::EOPNOTSUPP
41
+ nil
42
+ rescue Errno::ENOENT => e
43
+ puts e.to_s
44
+ exit -2
45
+ end
46
+ end.compact.select do |file|
47
+ file.file? || (options[:recursive] && file.directory?)
48
+ end.sort_by(&:ctime)
49
+ end
50
+
51
+ def files_to_delete
52
+ files_before_threshold - files_to_preserve
53
+ end
54
+
55
+ def files_before_threshold
56
+ files.select{|file| file.ctime < options[:threshold]}
57
+ end
58
+
59
+ def files_to_preserve
60
+ return [] if @key_intervals.nil?
61
+ files_before_threshold.group_by do |file|
62
+ cdate = file.ctime.to_datetime
63
+ @key_intervals.map{|interval| cdate.send(interval)}
64
+ end.map do |_, files|
65
+ files.first
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,90 @@
1
+ require 'optparse'
2
+ require 'active_support'
3
+ require 'fileutils'
4
+
5
+ require 'clean_files/cleaner'
6
+
7
+ module CleanFiles
8
+ class Runner
9
+ attr_reader :options
10
+
11
+ def initialize(arguments)
12
+ @arguments = arguments
13
+
14
+ # Set defaults
15
+ @options = Hash.new
16
+ @options[:threshold] = 1.month.ago
17
+ end
18
+
19
+ # Parse options, check arguments, then process the command
20
+ def run
21
+
22
+ if parsed_options? && arguments_valid?
23
+ Cleaner.new(@options.delete(:paths), @options).start
24
+ else
25
+ output_usage
26
+ end
27
+
28
+ end
29
+
30
+ protected
31
+
32
+ def parsed_options?
33
+
34
+ # Specify options
35
+ opts = OptionParser.new
36
+ opts.on('-h', '--help') { output_help }
37
+ opts.on('-v', '--verbose') { @options[:verbose] = true }
38
+ opts.on('-d', '--pretend') { @options[:pretend] = true
39
+ @options[:verbose] = true }
40
+ opts.on('-r', '--recursive') {@options[:recursive] = true }
41
+
42
+ opts.on('-t', '--treshold [DAYS]') do |days|
43
+ raise OptionParser::InvalidOption unless days.to_i > 0 || days == "0"
44
+ @options[:threshold] = days.to_i.send(:days).ago
45
+ end
46
+
47
+ Cleaner::VALID_INTERVALS.each do |interval|
48
+ opts.on("-#{interval.to_s.first.upcase}", "--#{interval}") {@options[interval] = true}
49
+ end
50
+ return false unless opts.parse!(@arguments)
51
+
52
+ @options[:paths] = @arguments.dup
53
+
54
+ true
55
+ end
56
+
57
+ def arguments_valid?
58
+ @options[:paths].present?
59
+ end
60
+
61
+ def output_help
62
+ rdoc
63
+ exit -1
64
+ end
65
+
66
+ def output_usage
67
+ rdoc('Usage', 'Options')
68
+ exit -1
69
+ end
70
+
71
+ def rdoc(*sections)
72
+ readme_path = File.join(File.dirname(__FILE__), '/../README.rdoc')
73
+ comment = File.read(readme_path)
74
+
75
+ markup = SM::SimpleMarkup.new
76
+ flow_convertor = SM::ToFlow.new
77
+ flow = markup.convert(comment, flow_convertor)
78
+
79
+ unless sections.empty?
80
+ flow = RDoc.extract_sections(flow, sections)
81
+ end
82
+
83
+ options = RI::Options.instance
84
+
85
+ formatter = options.formatter.new(options, "")
86
+ formatter.display_flow(flow)
87
+ end
88
+
89
+ end
90
+ end
data/lib/clean_files.rb CHANGED
@@ -1,91 +1,4 @@
1
- require 'optparse'
2
- require 'active_support'
3
- require 'fileutils'
4
-
5
- require 'cleaner'
6
-
7
- class CleanFiles
8
- VERSION = '0.1.0'
9
-
10
- attr_reader :options
11
-
12
- def initialize(arguments)
13
- @arguments = arguments
14
-
15
- # Set defaults
16
- @options = Hash.new
17
- @options[:threshold] = 1.month.ago
18
- end
19
-
20
- # Parse options, check arguments, then process the command
21
- def run
22
-
23
- if parsed_options? && arguments_valid?
24
- Cleaner.new(@options.delete(:paths), @options).start
25
- else
26
- output_usage
27
- end
28
-
29
- end
30
-
31
- protected
32
-
33
- def parsed_options?
34
-
35
- # Specify options
36
- opts = OptionParser.new
37
- opts.on('-h', '--help') { output_help }
38
- opts.on('-v', '--verbose') { @options[:verbose] = true }
39
- opts.on('-d', '--pretend') { @options[:pretend] = true
40
- @options[:verbose] = true }
41
- opts.on('-r', '--recursive') {@options[:recursive] = true }
42
-
43
- opts.on('-t', '--treshold [DAYS]') do |days|
44
- raise OptionParser::InvalidOption unless days.to_i > 0 || days == "0"
45
- @options[:threshold] = days.to_i.send(:days).ago
46
- end
47
-
48
- Cleaner::VALID_INTERVALS.each do |interval|
49
- opts.on("-#{interval.to_s.first.upcase}", "--#{interval}") {@options[interval] = true}
50
- end
51
- return false unless opts.parse!(@arguments)
52
-
53
- @options[:paths] = @arguments.dup
54
-
55
- true
56
- end
57
-
58
- def arguments_valid?
59
- @options[:paths].present?
60
- end
61
-
62
- def output_help
63
- rdoc
64
- exit -1
65
- end
66
-
67
- def output_usage
68
- rdoc('Usage', 'Options')
69
- exit -1
70
- end
71
-
72
- def rdoc(*sections)
73
- readme_path = File.join(File.dirname(__FILE__), '/../README.rdoc')
74
- comment = File.read(readme_path)
75
-
76
- markup = SM::SimpleMarkup.new
77
- flow_convertor = SM::ToFlow.new
78
- flow = markup.convert(comment, flow_convertor)
79
- format = "plain"
80
-
81
- unless sections.empty?
82
- flow = RDoc.extract_sections(flow, sections)
83
- end
84
-
85
- options = RI::Options.instance
86
-
87
- formatter = options.formatter.new(options, "")
88
- formatter.display_flow(flow)
89
- end
1
+ require 'clean_files/runner'
90
2
 
3
+ module CleanFiles
91
4
  end
data/spec/cleaner_spec.rb CHANGED
@@ -1,117 +1,119 @@
1
1
  require File.join(File.dirname(__FILE__), '/spec_helper')
2
-
3
- describe Cleaner do
4
-
5
- it 'find files older than threshold' do
6
- cleaner = Cleaner.new('/path', :threshold => 5.days.ago)
7
- cleaner.should_receive(:files).and_return(mock_files(7.days.ago, 4.days.ago))
8
- cleaner.files_before_threshold.should == mock_files(7.days.ago)
9
- end
10
-
11
- it 'deletes files' do
12
- cleaner = Cleaner.new('/path')
13
- files = mock_files(3.days.ago, 2.days.ago, 7.days.ago)
14
- cleaner.should_receive(:files_to_delete).and_return(files)
15
- FileUtils.should_receive(:rm_rf).with(files.map(&:path), :noop => false)
16
- cleaner.start
17
- end
18
-
19
- it 'does not delete any files if specifying pretend => true' do
20
- cleaner = Cleaner.new('/path', :pretend => true)
21
- files = mock_files(3.days.ago, 2.days.ago, 7.days.ago)
22
- cleaner.should_receive(:files_to_delete).and_return(files)
23
- FileUtils.should_receive(:rm_rf).with(files.map(&:path), :noop => true)
24
- cleaner.start
25
- end
26
-
27
- it 'has has files to delete' do
28
- cleaner = Cleaner.new('/path')
29
- cleaner.should_receive(:files_before_threshold).and_return(mock_files('12:00', '13:00'))
30
- cleaner.should_receive(:files_to_preserve).and_return(mock_files('13:00'))
31
- cleaner.files_to_delete.should == mock_files('12:00')
32
- end
33
-
34
- it 'prints name of file to be deleted if specifying verbose => true' do
35
- cleaner = Cleaner.new('/path', :verbose => true)
36
- files = mock_files('00:50', '13:30')
37
- cleaner.should_receive(:files_to_delete).and_return(files)
38
- FileUtils.should_receive(:rm_rf).with(files.map(&:path), :noop => false)
39
- cleaner.should_receive(:puts).with("01 May 00:50\n01 May 13:30")
40
- cleaner.start
41
- end
42
-
43
- it 'preserves the first file of the hour' do
44
- should_preserve(:hourly,
45
- '12:05' => true,
46
- '12:10' => false,
47
- '13:15' => true,
48
- '13:16' => false)
49
- end
50
-
51
- it 'preserves the first file of the day' do
52
- should_preserve(:daily,
53
- '01 10:00' => true,
54
- '01 12:00' => false,
55
- '02 00:00' => true,
56
- '02 00:01' => false)
57
- end
58
-
59
- it 'preserves the first file of the week' do
60
- should_preserve(:weekly,
61
- 'Sun Jan 02 03:40 00' => true,
62
- 'Tue Jan 04 03:40 00' => true,
63
- 'Wed Jan 05 03:40 00' => false)
64
- end
65
-
66
- it 'preserves the first file of the month' do
67
- should_preserve(:monthly,
68
- 'Sun Jan 02 12:00 00' => true,
69
- 'Tue Feb 01 12:00 00' => true,
70
- 'Wed Feb 02 12:00 00' => false)
71
- end
72
-
73
- it 'preserves the first file of the year' do
74
- should_preserve(:yearly,
75
- 'Sun Jan 02 03:40 01' => true,
76
- 'Tue Jan 04 03:40 02' => true,
77
- 'Wed Jan 05 03:40 02' => false)
78
- end
79
-
80
- MockFile = Struct.new(:ctime) do
81
- def ==(other)
82
- (ctime.to_i - other.ctime.to_i) < 2
2
+
3
+ module CleanFiles
4
+ describe Cleaner do
5
+
6
+ it 'find files older than threshold' do
7
+ cleaner = Cleaner.new('/path', :threshold => 5.days.ago)
8
+ cleaner.should_receive(:files).and_return(mock_files(7.days.ago, 4.days.ago))
9
+ cleaner.files_before_threshold.should == mock_files(7.days.ago)
10
+ end
11
+
12
+ it 'deletes files' do
13
+ cleaner = Cleaner.new('/path')
14
+ files = mock_files(3.days.ago, 2.days.ago, 7.days.ago)
15
+ cleaner.should_receive(:files_to_delete).and_return(files)
16
+ FileUtils.should_receive(:rm_rf).with(files.map(&:path), :noop => false)
17
+ cleaner.start
18
+ end
19
+
20
+ it 'does not delete any files if specifying pretend => true' do
21
+ cleaner = Cleaner.new('/path', :pretend => true)
22
+ files = mock_files(3.days.ago, 2.days.ago, 7.days.ago)
23
+ cleaner.should_receive(:files_to_delete).and_return(files)
24
+ FileUtils.should_receive(:rm_rf).with(files.map(&:path), :noop => true)
25
+ cleaner.start
83
26
  end
84
-
85
- def inspect
86
- ctime.to_s(:short)
27
+
28
+ it 'has has files to delete' do
29
+ cleaner = Cleaner.new('/path')
30
+ cleaner.should_receive(:files_before_threshold).and_return(mock_files('12:00', '13:00'))
31
+ cleaner.should_receive(:files_to_preserve).and_return(mock_files('13:00'))
32
+ cleaner.files_to_delete.should == mock_files('12:00')
87
33
  end
88
-
89
- def stat
90
- stat = Object.new
91
- def stat.file?
92
- true
34
+
35
+ it 'prints name of file to be deleted if specifying verbose => true' do
36
+ cleaner = Cleaner.new('/path', :verbose => true)
37
+ files = mock_files('00:50', '13:30')
38
+ cleaner.should_receive(:files_to_delete).and_return(files)
39
+ FileUtils.should_receive(:rm_rf).with(files.map(&:path), :noop => false)
40
+ cleaner.should_receive(:puts).with("01 May 00:50\n01 May 13:30")
41
+ cleaner.start
42
+ end
43
+
44
+ it 'preserves the first file of the hour' do
45
+ should_preserve(:hourly,
46
+ '12:05' => true,
47
+ '12:10' => false,
48
+ '13:15' => true,
49
+ '13:16' => false)
50
+ end
51
+
52
+ it 'preserves the first file of the day' do
53
+ should_preserve(:daily,
54
+ '01 10:00' => true,
55
+ '01 12:00' => false,
56
+ '02 00:00' => true,
57
+ '02 00:01' => false)
58
+ end
59
+
60
+ it 'preserves the first file of the week' do
61
+ should_preserve(:weekly,
62
+ 'Sun Jan 02 03:40 00' => true,
63
+ 'Tue Jan 04 03:40 00' => true,
64
+ 'Wed Jan 05 03:40 00' => false)
65
+ end
66
+
67
+ it 'preserves the first file of the month' do
68
+ should_preserve(:monthly,
69
+ 'Sun Jan 02 12:00 00' => true,
70
+ 'Tue Feb 01 12:00 00' => true,
71
+ 'Wed Feb 02 12:00 00' => false)
72
+ end
73
+
74
+ it 'preserves the first file of the year' do
75
+ should_preserve(:yearly,
76
+ 'Sun Jan 02 03:40 01' => true,
77
+ 'Tue Jan 04 03:40 02' => true,
78
+ 'Wed Jan 05 03:40 02' => false)
79
+ end
80
+
81
+ MockFile = Struct.new(:ctime) do
82
+ def ==(other)
83
+ (ctime.to_i - other.ctime.to_i) < 2
93
84
  end
94
- stat
85
+
86
+ def inspect
87
+ ctime.to_s(:short)
88
+ end
89
+
90
+ def stat
91
+ stat = Object.new
92
+ def stat.file?
93
+ true
94
+ end
95
+ stat
96
+ end
97
+
98
+ alias path inspect
95
99
  end
96
-
97
- alias path inspect
98
- end
99
100
 
100
- def mock_files(*ctimes)
101
- ctimes.map do |ctime|
102
- if ctime.is_a?(String)
103
- ctime = "1 May #{ctime}" unless ctime =~ /\d\d /
104
- ctime = "May #{ctime} 2009" unless ctime =~ /\d{2}/
105
- ctime = Time.parse(ctime)
101
+ def mock_files(*ctimes)
102
+ ctimes.map do |ctime|
103
+ if ctime.is_a?(String)
104
+ ctime = "1 May #{ctime}" unless ctime =~ /\d\d /
105
+ ctime = "May #{ctime} 2009" unless ctime =~ /\d{2}/
106
+ ctime = Time.parse(ctime)
107
+ end
108
+ MockFile.new(ctime)
106
109
  end
107
- MockFile.new(ctime)
108
110
  end
109
- end
110
-
111
- def should_preserve(interval, files)
112
- cleaner = Cleaner.new('/path', interval => true)
113
- cleaner.should_receive(:files_before_threshold).and_return(mock_files(*files.keys.sort))
114
- expected_files = files.select{|_, select| select == true}.map{|file, _| file}
115
- cleaner.files_to_preserve.to_set.should == mock_files(*expected_files).to_set
111
+
112
+ def should_preserve(interval, files)
113
+ cleaner = Cleaner.new('/path', interval => true)
114
+ cleaner.should_receive(:files_before_threshold).and_return(mock_files(*files.keys.sort))
115
+ expected_files = files.select{|_, select| select == true}.map{|file, _| file}
116
+ cleaner.files_to_preserve.to_set.should == mock_files(*expected_files).to_set
117
+ end
116
118
  end
117
119
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clean_files
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tor Erik Linnerud
@@ -66,7 +66,8 @@ dependencies:
66
66
  - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- description:
69
+ description: Executable to delete files which fit certain criteria e.g. you can delete
70
+ files older than 1 month keeping one weekly file
70
71
  email: torerik.linnerud@alphasights.com
71
72
  executables: []
72
73
  extensions: []
@@ -80,15 +81,17 @@ files:
80
81
  - Gemfile.lock
81
82
  - LICENSE
82
83
  - README.rdoc
83
- - VERSION.yml
84
84
  - bin/clean_files
85
+ - clean_files-1.0.1.gem
85
86
  - clean_files.gemspec
86
87
  - lib/clean_files.rb
87
- - lib/cleaner.rb
88
+ - lib/clean_files/cleaner.rb
89
+ - lib/clean_files/runner.rb
88
90
  - spec/cleaner_spec.rb
89
91
  - spec/spec_helper.rb
90
- homepage: http://github.com/alphasights/clean-files
91
- licenses: []
92
+ homepage: http://github.com/alphasights/clean_files
93
+ licenses:
94
+ - MIT
92
95
  metadata: {}
93
96
  post_install_message:
94
97
  rdoc_options:
data/VERSION.yml DELETED
@@ -1,4 +0,0 @@
1
- ---
2
- :major: 1
3
- :minor: 0
4
- :patch: 1
data/lib/cleaner.rb DELETED
@@ -1,66 +0,0 @@
1
- require 'active_support/core_ext'
2
- class Cleaner
3
- attr_reader :paths, :options
4
-
5
- VALID_OPTIONS = [:threshold, :pretend, :verbose, :recursive]
6
- VALID_INTERVALS = [:hourly, :daily, :weekly, :monthly, :yearly]
7
- TIME_INTERVALS = [:hour, :day, :cweek, :month, :year]
8
-
9
- SimpleFile = Struct.new(:path, :stat) do
10
- delegate :ctime, :file?, :directory?, :to => :stat
11
- end
12
-
13
- def initialize(paths, options = {})
14
- @paths = [paths].flatten
15
- @options = options.reverse_merge(:threshold => 30.days.ago)
16
- options.assert_valid_keys(VALID_OPTIONS + VALID_INTERVALS)
17
- given_intervals = VALID_INTERVALS & options.keys
18
- if given_intervals.present?
19
- lowest_selected_position = VALID_INTERVALS.index(given_intervals.first)
20
- @key_intervals = TIME_INTERVALS[lowest_selected_position..-1]
21
- end
22
- end
23
-
24
- def start
25
- files = files_to_delete.map(&:path)
26
- puts files.join("\n") if options[:verbose]
27
- FileUtils.rm_rf(files, :noop => !!options[:pretend])
28
- end
29
-
30
- def files
31
- if paths.any?{|path| path.include?('*')}
32
- paths.map!{|path| Dir.glob(path)}
33
- paths.flatten!
34
- end
35
- @_files ||= paths.map do |file_path|
36
- begin
37
- SimpleFile.new(file_path, File.stat(file_path))
38
- rescue Errno::EOPNOTSUPP
39
- nil
40
- rescue Errno::ENOENT => e
41
- puts e.to_s
42
- exit -2
43
- end
44
- end.compact.select do |file|
45
- file.file? || (options[:recursive] && file.directory?)
46
- end.sort_by(&:ctime)
47
- end
48
-
49
- def files_to_delete
50
- files_before_threshold - files_to_preserve
51
- end
52
-
53
- def files_before_threshold
54
- files.select{|file| file.ctime < options[:threshold]}
55
- end
56
-
57
- def files_to_preserve
58
- return [] if @key_intervals.nil?
59
- files_before_threshold.group_by do |file|
60
- cdate = file.ctime.to_datetime
61
- @key_intervals.map{|interval| cdate.send(interval)}
62
- end.map do |_, files|
63
- files.first
64
- end
65
- end
66
- end