crf 0.0.7 → 0.0.8

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: cedcfa93b22235198b5fe6cb7390bdee22f02109
4
- data.tar.gz: fe5131cf2039948c9ffa7db13a7ced10d8f6f1a2
3
+ metadata.gz: 3b6b40091e9563035ada765e0622007dd18d27fc
4
+ data.tar.gz: 752bac46aef9db45980de0c18bbb65d8ac93cd16
5
5
  SHA512:
6
- metadata.gz: 48487f353a617433b44ffc1514dc92fed3e365e4422a626e8ba28bbffb82b5859088649599e7fb142198d96174ecb7ffd95b41daf93766b8def8a36d2852ac11
7
- data.tar.gz: f1a8b5badf11ede2776637900365fb49b132f34fcd65c02da7a2ed6b0772ed01d2484eca4f0a147d1951db4be8366b3b1644d7231545101054469e332f4a69d5
6
+ metadata.gz: 7111b4a41c5a117b54ea62f2e4a73444c680b26c9630c1b97425e09ff6974a6203150510a6abdc8def73a8fe90ca57520b0fe1e6dc62ea2abd5011895ac6bf9b
7
+ data.tar.gz: 1740bd54e2394b4e72bb04b25327a4a15264ca1eb4094e278e69d02883495b78f7cbb7ffd2bb44d9e7bf6bceead806c012896bd290b043655b977f95b4040674
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -4,7 +4,7 @@ AllCops:
4
4
  - bin/crf
5
5
 
6
6
  Documentation:
7
- Enabled: true
7
+ Enabled: false
8
8
 
9
9
  LineLength:
10
10
  Max: 99
@@ -1,6 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.3
4
3
  - 2.0.0
5
4
  - 2.1
6
5
  - 2.2
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in crf.gemspec
4
4
  gemspec
5
5
 
6
- gem 'rake', '~> 10.0'
6
+ gem 'rake', '~> 11.1'
7
7
  gem 'rspec', '~> 3.4'
8
8
 
9
9
  group :test do
data/bin/crf CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'crf'
4
+ require 'crf/version'
4
5
  require 'optparse'
5
6
 
6
7
  options = { interactive: true, progress: true, fast: false }
@@ -20,6 +21,11 @@ parser = OptionParser.new do |opts|
20
21
  options[:progress] = false
21
22
  end
22
23
 
24
+ opts.on('-v', '--version', 'Displays version') do
25
+ puts "CRF Version: #{Crf::VERSION}"
26
+ exit
27
+ end
28
+
23
29
  opts.on('-h', '--help', 'Displays help') do
24
30
  puts opts
25
31
  exit
@@ -28,8 +34,11 @@ end
28
34
 
29
35
  parser.parse!
30
36
 
31
- if !ARGV[0].nil? && File.directory?(ARGV[0])
32
- Crf::Checker.new(ARGV[0], options).check_repeated_files
37
+ paths = []
38
+ ARGV.each { |arg| paths << arg if File.directory?(arg) }
39
+
40
+ unless paths.empty?
41
+ Crf::Checker.new(paths, options).check_repeated_files
33
42
  else
34
43
  STDOUT.puts 'No directory specified.'
35
44
  end
@@ -23,6 +23,6 @@ Gem::Specification.new do |spec|
23
23
  spec.add_dependency 'ruby-progressbar', '~> 1.7', '>= 1.7.0'
24
24
 
25
25
  spec.add_development_dependency 'bundler', '>= 1.3.0', '< 2.0'
26
- spec.add_development_dependency 'byebug' if RUBY_VERSION >= '2.0.0'
27
- spec.add_development_dependency 'rubocop'
26
+ spec.add_development_dependency 'byebug', '~> 9.0', '>= 9.0.5' if RUBY_VERSION >= '2.0.0'
27
+ spec.add_development_dependency 'rubocop', '~> 0.38', '>= 0.37.2'
28
28
  end
data/lib/crf.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'crf/version'
1
2
  require 'crf/finder'
2
3
  require 'crf/interactive_finder'
3
4
  require 'crf/remover'
@@ -7,30 +8,22 @@ require 'crf/configuration'
7
8
  require 'colorize'
8
9
 
9
10
  module Crf
10
- #
11
- # This class is the Crf starting point.
12
- #
13
11
  class Checker
14
- #
15
- # The path where it will look for repetitions, the options provided, the repetitions found
16
- # and the logger files are accesible from the outside and used in the class.
17
- #
18
- attr_reader :path, :options, :repetitions, :logger
12
+ attr_reader :paths, :options, :repetitions, :logger
19
13
 
20
14
  #
21
- # Creates the object saving the directory's path and options provided. Options are set to
15
+ # Creates the object saving the paths and options provided. Options are set to
22
16
  # default if they are not given. It also creates the logger file.
23
17
  #
24
- def initialize(path, options = { interactive: false, progress: false, fast: false })
25
- @path = path
18
+ # @param path [Arsray] array of paths where the scan will start
19
+ # @param options [Hash] hash indicating the options of the scan
20
+ #
21
+ def initialize(paths, options = { interactive: false, progress: false, fast: false })
22
+ @paths = paths
26
23
  @options = options
27
24
  @logger = Crf::Logger.new
28
25
  end
29
26
 
30
- #
31
- # Starting point of Crf. You should call this if you want to check if a directory has
32
- # duplicated files inside.
33
- #
34
27
  def check_repeated_files
35
28
  find_repetitions
36
29
  return no_repetitions_found if repetitions.empty?
@@ -40,15 +33,18 @@ module Crf
40
33
  private
41
34
 
42
35
  def find_repetitions
43
- logger.write "Looking for repetitions in #{path}"
44
- finder = if options[:progress]
45
- Crf::InteractiveFinder.new(path, options[:fast])
46
- else
47
- Crf::Finder.new(path, options[:fast])
48
- end
36
+ logger.write "Looking for repetitions in #{paths}"
49
37
  @repetitions = finder.search_repeated_files
50
38
  end
51
39
 
40
+ def finder
41
+ unless instance_variable_defined?(:@finder)
42
+ @finder = Crf::InteractiveFinder.new(paths, options[:fast]) if options[:progress]
43
+ @finder = Crf::Finder.new(paths, options[:fast]) unless options[:progress]
44
+ end
45
+ @finder
46
+ end
47
+
52
48
  def no_repetitions_found
53
49
  logger.write 'No repetitions found'
54
50
  STDOUT.puts 'No repetitions found'.blue
@@ -62,9 +58,8 @@ module Crf
62
58
  end
63
59
 
64
60
  def remove_repetitions
65
- remover = Crf::Remover.new(repetitions, logger) unless options[:interactive]
66
- remover = Crf::InteractiveRemover.new(repetitions, logger) if options[:interactive]
67
- remover.remove
61
+ return Crf::InteractiveRemover.new(repetitions, logger).remove if options[:interactive]
62
+ Crf::Remover.new(repetitions, logger).remove
68
63
  end
69
64
 
70
65
  def number_to_human_size(size)
@@ -1,6 +1,3 @@
1
- #
2
- # Crf configuration
3
- #
4
1
  module Crf
5
2
  GEM_NAME = 'CRF'.freeze
6
3
  LOGGER_DATE_TIME_FORMAT = '%Y-%m-%d %H:%M:%S'.freeze
@@ -1,30 +1,24 @@
1
1
  require 'crf/repetitions_list'
2
2
  require 'digest'
3
3
  require 'ruby-progressbar'
4
+ require 'byebug'
4
5
 
5
6
  module Crf
6
- #
7
- # This class finds the paths of all the repeated files inside the path passed as argument.
8
- # All files repeated have the same file_identifier and file_hash.
9
- #
10
7
  class Finder
11
- #
12
- # The original path provided and the list of files inside it are accessible from the outside.
13
- #
14
- attr_reader :path, :paths, :repetitions
8
+ attr_reader :paths, :repetitions, :files
15
9
 
16
- #
10
+ ##
17
11
  # Creates the Finder object with a directory where it will look for duplicate files.
18
12
  # Path is the string representation of the absolute path of the directory.
19
13
  #
20
- def initialize(path, fast = false)
21
- @path = path
14
+ # @param paths [Array] paths of the folders where the scan will start.
15
+ # @param fast [Boolean] boolean indicating if this class will make a fast scan or not.
16
+ #
17
+ def initialize(paths, fast = false)
18
+ @paths = paths
22
19
  @fast = fast
23
20
  end
24
21
 
25
- #
26
- # Method that looks for the repeated files in the path specified when the object was created.
27
- #
28
22
  def search_repeated_files
29
23
  @repetitions = first_run
30
24
  return repetitions if repetitions.empty? || @fast
@@ -33,28 +27,26 @@ module Crf
33
27
 
34
28
  private
35
29
 
36
- #
37
- # Gets all file paths in the given directory and subdirectories.
38
- #
39
- def all_files(path)
40
- @paths = []
41
- Dir["#{path.chomp('/')}/**/*"].each { |p| paths << p.freeze if file?(p) }
42
- paths
30
+ def all_files
31
+ @files = []
32
+ paths.each do |path|
33
+ Dir["#{path.chomp('/')}/**/*"].each do |file_path|
34
+ @files << file_path.freeze if file?(file_path) && !@files.include?(file_path)
35
+ end
36
+ end
37
+ @files
43
38
  end
44
39
 
45
- #
46
- # Checks if the file is not a symlink or a directory.
47
- #
48
40
  def file?(path)
49
41
  !File.directory?(path) && !File.symlink?(path)
50
42
  end
51
43
 
52
- #
44
+ ##
53
45
  # This looks for the files with the same size only
54
46
  #
55
47
  def first_run
56
48
  repetitions_list = Crf::RepetitionsList.new
57
- all_files(path).each do |file_path|
49
+ all_files.each do |file_path|
58
50
  repetitions_list.add(file_identifier(file_path).freeze, file_path)
59
51
  end
60
52
  repetitions_list.repetitions
@@ -64,7 +56,7 @@ module Crf
64
56
  File.size(path).to_s
65
57
  end
66
58
 
67
- #
59
+ ##
68
60
  # After finding files with the same size, perform a deeper analysis of those
69
61
  #
70
62
  def second_run(repetitions)
@@ -2,17 +2,9 @@ require 'crf/repetitions_list'
2
2
  require 'ruby-progressbar'
3
3
 
4
4
  module Crf
5
- #
6
- # This class finds the paths of all the repeated files inside the path passed as argument.
7
- # All files repeated have the same file_identifier and file_hash.
8
- #
9
5
  class InteractiveFinder < Crf::Finder
10
- #
11
- # Method that looks for the repeated files in the path specified when the object was created
12
- # showing progress bars.
13
- #
14
6
  def search_repeated_files
15
- all_paths = all_files(path)
7
+ all_paths = all_files
16
8
  progressbar = ProgressBar.create(title: 'First run', total: all_paths.count,
17
9
  format: '%t: %c/%C %a |%B| %%%P')
18
10
  rep_list = first_run(progressbar)
@@ -22,12 +14,9 @@ module Crf
22
14
 
23
15
  private
24
16
 
25
- #
26
- # This looks for the files with the same size only
27
- #
28
17
  def first_run(progressbar)
29
18
  repetitions_list = Crf::RepetitionsList.new
30
- all_files(path).each do |file_path|
19
+ all_files.each do |file_path|
31
20
  repetitions_list.add(file_identifier(file_path), file_path)
32
21
  progressbar.increment
33
22
  end
@@ -1,15 +1,8 @@
1
1
  require 'colorize'
2
+ require 'pp'
2
3
 
3
4
  module Crf
4
- #
5
- # This is a subclass of Crf::Remover.
6
- # It asks the user if he/she wants to remove each file.
7
- #
8
5
  class InteractiveRemover < Crf::Remover
9
- #
10
- # This method asks the user if he/she wants to delete each of the files contained in the values
11
- # of the repetitions hash.
12
- #
13
6
  def remove
14
7
  saved = 0
15
8
  repetitions.each_value do |paths|
@@ -25,13 +18,13 @@ module Crf
25
18
 
26
19
  def print_all_paths(paths)
27
20
  STDOUT.puts 'Found this repetitions:'.green
28
- STDOUT.puts paths.to_s.green
21
+ STDOUT.puts paths.pretty_inspect.green
29
22
  end
30
23
 
31
24
  def remove_confirmation(path)
32
25
  STDOUT.print "Do you want to delete the file #{path}? [y/n] ".yellow
33
26
  logger.write "Asking to remove #{path}"
34
- answer = STDIN.gets.chomp
27
+ answer = $stdin.gets.chomp
35
28
  logger.write "User input: #{answer}"
36
29
  if answer == 'y'
37
30
  STDOUT.puts "Removed #{path}".red
@@ -1,23 +1,19 @@
1
1
  require 'logger'
2
2
 
3
3
  module Crf
4
- #
5
- # This class is a wrapper of the Logger class, it hanldes the creation and sets the configuration
6
- #
7
4
  class Logger
8
- #
5
+ ##
9
6
  # Creates the logger with the configurations in the path provided or in the current directory
10
7
  #
8
+ # @param path [String] path where the logger is or will be created.
9
+ #
11
10
  def initialize(path = 'crf.log')
12
11
  @logger = ::Logger.new(path, File::CREAT)
13
12
  configurate_logger
14
13
  end
15
14
 
16
- #
17
- # Wrapper of the Logger info method
18
- #
19
- def write(msg)
20
- @logger.info msg
15
+ def write(message)
16
+ @logger.info message
21
17
  end
22
18
 
23
19
  private
@@ -25,8 +21,8 @@ module Crf
25
21
  def configurate_logger
26
22
  @logger.datetime_format = Crf::LOGGER_DATE_TIME_FORMAT
27
23
  @logger.progname = Crf::GEM_NAME
28
- @logger.formatter = proc do |_severity, datetime, progname, msg|
29
- "[#{datetime}] #{progname}: #{msg}\n"
24
+ @logger.formatter = proc do |_severity, date_time, program_name, message|
25
+ "[#{date_time}] #{program_name}: #{message}\n"
30
26
  end
31
27
  end
32
28
  end
@@ -1,25 +1,21 @@
1
1
  module Crf
2
- #
3
- # This class removes all the repetitions passed as an argument.
4
- # It saves the first element of the repetitions and deletes the rest.
5
- #
6
2
  class Remover
7
- #
8
- # The repetitions hash and the logger file are accessible from the outside.
9
- #
10
3
  attr_reader :repetitions, :logger
11
4
 
12
- #
5
+ ##
13
6
  # This object needs the repeated files obtained with Crf::Finder and the logger object.
14
7
  #
8
+ # @param repetitions [Hash] repetitions found by one of the finder classes.
9
+ # @param logger [Crf::Logger] logger file which this class will write.
10
+ #
15
11
  def initialize(repetitions, logger)
16
12
  @repetitions = repetitions
17
13
  @logger = logger
18
14
  end
19
15
 
20
- #
16
+ ##
21
17
  # This method removes all the files contained on each value of the repetitions hash
22
- # except the first one. This is done without asking the user for confirmation so be careful.
18
+ # except the first one. This is done without asking the user for confirmation.
23
19
  #
24
20
  def remove
25
21
  saved = 0
@@ -36,13 +32,11 @@ module Crf
36
32
 
37
33
  def remove_file(path)
38
34
  size = File.size(path)
39
- begin
40
- File.delete(path)
41
- log_removal(path, size)
42
- return size
43
- rescue
44
- return 0
45
- end
35
+ File.delete(path)
36
+ log_removal(path, size)
37
+ return size
38
+ rescue
39
+ return 0
46
40
  end
47
41
 
48
42
  def log_removal(path, size)
@@ -1,27 +1,20 @@
1
1
  module Crf
2
- #
3
- # This is the data structure used to get the repeated files.
4
- #
5
2
  class RepetitionsList
6
- #
7
- # The uniques and repetitions hashes can be accessed from the outside, along with the
8
- # total repetitions count.
9
- #
10
3
  attr_reader :uniques, :repetitions, :total_repetitions
11
4
 
12
- #
13
- # Creates the RepetitionsList object with everything it needs.
14
- #
15
5
  def initialize
16
6
  @uniques = {}
17
7
  @repetitions = {}
18
8
  @total_repetitions = 0
19
9
  end
20
10
 
21
- #
11
+ ##
22
12
  # Adds an element to one of each hashes. If the value is repeated, then it erases it from
23
13
  # uniques and adds it in the repetitions hash along with the duplicate.
24
14
  #
15
+ # @param key result of the function that identifies the file
16
+ # @param value [String] path of the file
17
+ #
25
18
  def add(key, value)
26
19
  if repetitions.key?(key)
27
20
  repetitions[key] << value
@@ -1,6 +1,3 @@
1
- #
2
- # Crf version
3
- #
4
1
  module Crf
5
- VERSION = '0.0.7'.freeze
2
+ VERSION = '0.0.8'.freeze
6
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alejandro Bezdjian
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-24 00:00:00.000000000 Z
11
+ date: 2016-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -74,30 +74,42 @@ dependencies:
74
74
  name: byebug
75
75
  requirement: !ruby/object:Gem::Requirement
76
76
  requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '9.0'
77
80
  - - ">="
78
81
  - !ruby/object:Gem::Version
79
- version: '0'
82
+ version: 9.0.5
80
83
  type: :development
81
84
  prerelease: false
82
85
  version_requirements: !ruby/object:Gem::Requirement
83
86
  requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '9.0'
84
90
  - - ">="
85
91
  - !ruby/object:Gem::Version
86
- version: '0'
92
+ version: 9.0.5
87
93
  - !ruby/object:Gem::Dependency
88
94
  name: rubocop
89
95
  requirement: !ruby/object:Gem::Requirement
90
96
  requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: '0.38'
91
100
  - - ">="
92
101
  - !ruby/object:Gem::Version
93
- version: '0'
102
+ version: 0.37.2
94
103
  type: :development
95
104
  prerelease: false
96
105
  version_requirements: !ruby/object:Gem::Requirement
97
106
  requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '0.38'
98
110
  - - ">="
99
111
  - !ruby/object:Gem::Version
100
- version: '0'
112
+ version: 0.37.2
101
113
  description: Library that looks for exact duplicated files in a directory.
102
114
  email: alebezdjian@gmail.com
103
115
  executables:
@@ -106,6 +118,7 @@ extensions: []
106
118
  extra_rdoc_files: []
107
119
  files:
108
120
  - ".gitignore"
121
+ - ".rspec"
109
122
  - ".rubocop.yml"
110
123
  - ".travis.yml"
111
124
  - Gemfile
@@ -143,9 +156,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
143
156
  version: '0'
144
157
  requirements: []
145
158
  rubyforge_project:
146
- rubygems_version: 2.5.1
159
+ rubygems_version: 2.4.5.1
147
160
  signing_key:
148
161
  specification_version: 4
149
162
  summary: Look for exact duplicated files.
150
163
  test_files: []
151
- has_rdoc: