rdupes 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/exe/rdupes +4 -0
- data/lib/rdupes.rb +40 -12
- data/lib/rdupes/version.rb +1 -1
- data/rdupes.gemspec +1 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52c253e303c1b31d334dbaae5354cafc18397db2
|
4
|
+
data.tar.gz: 27bff2346e926eb9f483390048dcaff908a1f907
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce5fdaf876597b5e329db389b87c6b3144d886437f961ff3b22e7755c83a7e8c95159cac3887091ed89bc9579b9cb5e1c949afe90320be9efe9baf62125a8c1a
|
7
|
+
data.tar.gz: 3c235c3dd62631e8eb33088d4f5ef15f86246eb88317d4978fe319cbcafa7e9d5cd0181516791c9888dfe18621ca734fe071b33b68fe88d0dc44a74561b4e37a
|
data/exe/rdupes
CHANGED
@@ -12,6 +12,10 @@ opt_parser = OptionParser.new do |opts|
|
|
12
12
|
rdupe.add_reference_directory directory
|
13
13
|
end
|
14
14
|
|
15
|
+
opts.on("-d", "--dryrun", "Runs the analysis but without any file deletion") do |q|
|
16
|
+
rdupe.dry_run!
|
17
|
+
end
|
18
|
+
|
15
19
|
opts.on("-q", "--quiet", "Runs quietly") do |q|
|
16
20
|
rdupe.quiet!
|
17
21
|
end
|
data/lib/rdupes.rb
CHANGED
@@ -2,6 +2,7 @@ require "rdupes/version"
|
|
2
2
|
require 'logger'
|
3
3
|
require 'shellwords'
|
4
4
|
require 'tmpdir'
|
5
|
+
require 'colorize'
|
5
6
|
|
6
7
|
module Rdupes
|
7
8
|
class Finder
|
@@ -15,16 +16,24 @@ module Rdupes
|
|
15
16
|
@counters = Hash.new(0)
|
16
17
|
@quiet = false
|
17
18
|
@keep = false
|
19
|
+
@dry_run = false
|
18
20
|
end
|
19
21
|
|
20
22
|
def quiet!
|
23
|
+
@logger.debug "Enabling quiet mode"
|
21
24
|
@quiet = true
|
22
25
|
end
|
23
26
|
|
24
27
|
def keep!
|
28
|
+
@logger.debug "Enabling keep mode. Will keep the fdupes output"
|
25
29
|
@keep = true
|
26
30
|
end
|
27
31
|
|
32
|
+
def dry_run!
|
33
|
+
@logger.debug "Enabling dry run mode"
|
34
|
+
@dry_run = true
|
35
|
+
end
|
36
|
+
|
28
37
|
def add_reference_directory(directory)
|
29
38
|
directory_path = File.expand_path(directory)
|
30
39
|
@logger.debug "Adding #{directory_path} to the reference directories"
|
@@ -47,26 +56,37 @@ module Rdupes
|
|
47
56
|
raise 'No directories provided for duplicate search' if @search_directories.empty?
|
48
57
|
raise 'fdupes needs to be installed' unless command? 'fdupes'
|
49
58
|
|
50
|
-
|
51
|
-
|
52
|
-
puts "Reference directory: #{@reference_directories}"
|
53
|
-
end
|
59
|
+
say "Processing #{@search_directories}"
|
60
|
+
say "Reference directory: #{@reference_directories}"
|
54
61
|
|
55
62
|
Dir.mktmpdir do |dir|
|
56
|
-
|
63
|
+
fdupes_output = File.join(dir, 'duplicates.log')
|
57
64
|
# Redirect to file
|
58
|
-
cmd = "fdupes -rq #{directories_for_search.shelljoin} > #{
|
65
|
+
cmd = "fdupes -rq #{directories_for_search.shelljoin} > #{fdupes_output}"
|
59
66
|
@logger.debug "Executing: #{cmd}"
|
60
67
|
r = system cmd
|
61
68
|
raise "fdupe crashed " unless r
|
62
|
-
process_fdupes_result(
|
63
|
-
|
64
|
-
|
69
|
+
process_fdupes_result(fdupes_output)
|
70
|
+
|
71
|
+
if @keep
|
72
|
+
fdupes_output_copy = "#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}_duplicates.log"
|
73
|
+
say "Copying fdupes result to #{fdupes_output_copy}"
|
74
|
+
FileUtils.cp fdupes_output, fdupes_output_copy
|
75
|
+
end
|
76
|
+
|
77
|
+
say "Found #{@counters[:duplicate_groups]} duplicate groups"
|
78
|
+
say "Found #{@counters[:duplicate_entries]} duplicate entries"
|
79
|
+
say "Flagged #{@counters[:flag_for_delete]} files for deletion"
|
80
|
+
say "Deleted #{@counters[:deleted]} files"
|
65
81
|
end
|
66
82
|
end
|
67
83
|
|
68
84
|
private
|
69
85
|
|
86
|
+
def say(text)
|
87
|
+
puts text unless @quiet
|
88
|
+
end
|
89
|
+
|
70
90
|
def command?(command)
|
71
91
|
system("which #{ command} > /dev/null 2>&1")
|
72
92
|
end
|
@@ -91,18 +111,26 @@ module Rdupes
|
|
91
111
|
|
92
112
|
def handle_duplicate_group(duplicate_group)
|
93
113
|
@logger.debug "Handling group of #{duplicate_group.size} duplicates"
|
114
|
+
say "#{'==>'.blue} Group of #{duplicate_group.size} duplicates"
|
115
|
+
@counters[:duplicate_groups] += 1
|
116
|
+
@counters[:duplicate_entries] += duplicate_group.size
|
94
117
|
reference_files, duplicate_files = duplicate_group.partition do |f|
|
95
118
|
@reference_directories.any? { |rf| File.expand_path(f).start_with?(rf) }
|
96
119
|
end
|
97
120
|
# Keep the first duplicate if there is no reference file.
|
98
|
-
duplicate_files.shift if reference_files.empty?
|
121
|
+
say "- #{duplicate_files.shift}".green if reference_files.empty?
|
122
|
+
reference_files.each { |rf| say "- #{rf}".green }
|
99
123
|
duplicate_files.each { |dp| handle_duplicate_file(dp) }
|
100
124
|
end
|
101
125
|
|
102
126
|
def handle_duplicate_file(duplicate_file)
|
103
|
-
@counters[:deleted] += 1
|
104
127
|
@logger.debug "Handling duplicate #{duplicate_file}"
|
105
|
-
|
128
|
+
@counters[:flag_for_delete] += 1
|
129
|
+
say "- #{duplicate_file}".red
|
130
|
+
unless @dry_run
|
131
|
+
File.delete(duplicate_file)
|
132
|
+
@counters[:deleted] += 1
|
133
|
+
end
|
106
134
|
end
|
107
135
|
end
|
108
136
|
end
|
data/lib/rdupes/version.rb
CHANGED
data/rdupes.gemspec
CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
|
+
spec.add_dependency "colorize"
|
22
23
|
spec.add_development_dependency "bundler", "~> 1.13"
|
23
24
|
spec.add_development_dependency "rake", "~> 10.0"
|
24
25
|
spec.add_development_dependency "rspec", "~> 3.0"
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rdupes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Harold Waterkeyn
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: colorize
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|