From ac104732916ca3d74da75613d2fd010623b202ac Mon Sep 17 00:00:00 2001 From: lukeify <5379845+lukeify@users.noreply.github.com> Date: Sun, 20 Oct 2024 13:28:16 +1300 Subject: [PATCH 1/5] chore: copy both shell and ruby scripts --- setup.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup.sh b/setup.sh index 0245b91..7d63afc 100644 --- a/setup.sh +++ b/setup.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash -for file in src/*.sh; do - cp "$file" "${file%.sh}" +for file in src/*.{sh,rb}; do + [ -e "$file" ] || continue + cp "$file" "${file%.*}" done From 41fec787fe20b4632b58fd79a4c597e8247f8882 Mon Sep 17 00:00:00 2001 From: lukeify <5379845+lukeify@users.noreply.github.com> Date: Sun, 20 Oct 2024 13:30:55 +1300 Subject: [PATCH 2/5] docs: add commentary for ruby files --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index da9755e..828251b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # scripts -A collection of scripts that contain useful utilities and functions. +A collection of scripts that contain useful utilities and functions. +Most scripts are written for bash/zsh shell in mind, although some are Ruby files which will need the Ruby interpreter to function. -On Linux, run `setup.sh` with admin privileges to automatically copy over shell scripts into `/usr/local/bin`. +On Linux, run `setup.sh` with admin privileges to automatically copy over these scripts into `/usr/local/bin`. From 737e10a05ff184568b7149fcd9b03c6c04d0b605 Mon Sep 17 00:00:00 2001 From: lukeify <5379845+lukeify@users.noreply.github.com> Date: Sun, 20 Oct 2024 14:15:35 +1300 Subject: [PATCH 3/5] feat: initial duplication functionality --- src/sharpener.rb | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100755 src/sharpener.rb diff --git a/src/sharpener.rb b/src/sharpener.rb new file mode 100755 index 0000000..86d1f50 --- /dev/null +++ b/src/sharpener.rb @@ -0,0 +1,49 @@ +#!/usr/bin/env ruby + +require "find" +require "openssl" + +$duplicates_increment = 0 +$files_increment = 0 + +def log_duplicate_progress(is_duplicate:) + $duplicates_increment += 1 if is_duplicate + + print "\r#{$duplicates_increment} duplicates / #{$files_increment} files scanned" + $files_increment += 1 +end + +def find_dupes(target) + duplicates = {} + + Find.find(target) do |path| + if FileTest.file?(path) + dgst = OpenSSL::Digest::SHA256.file(path).hexdigest + + log_duplicate_progress(is_duplicate: duplicates.key?(dgst)) + + duplicates[dgst] = [] unless duplicates.key?(dgst) + duplicates[dgst] << path + end + end + + puts "\n===" + duplicates.select { |k, v| v.size > 1 }.each do |k, v| + puts "duplicate: #{k}" + puts v + end +end + +def find_unqiues(source, target) + +end + +case ARGV[0] +when "duplicates" + find_dupes(ARGV[1]) +when "uniques" + find_uniques(ARGV[1], ARGV[2]) +else + STDERR.puts "Please provide either 'duplicates' or 'uniques' to 'sharpener'." + exit(1) +end \ No newline at end of file From ee2cea6e64d0d165cb39fd6a5befd7240bdf0d21 Mon Sep 17 00:00:00 2001 From: lukeify <5379845+lukeify@users.noreply.github.com> Date: Sun, 20 Oct 2024 15:01:24 +1300 Subject: [PATCH 4/5] fix: ignore hidden directories and files --- src/sharpener.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sharpener.rb b/src/sharpener.rb index 86d1f50..95aec6b 100755 --- a/src/sharpener.rb +++ b/src/sharpener.rb @@ -17,6 +17,8 @@ def find_dupes(target) duplicates = {} Find.find(target) do |path| + Find.prune if File.basename(path).start_with?(".") + if FileTest.file?(path) dgst = OpenSSL::Digest::SHA256.file(path).hexdigest From 3e1d79817545ac5eb202d15812b2d04bc48eecd5 Mon Sep 17 00:00:00 2001 From: lukeify <5379845+lukeify@users.noreply.github.com> Date: Sun, 20 Oct 2024 17:32:57 +1300 Subject: [PATCH 5/5] refactor: method documentation, cleanup --- src/sharpener.rb | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/src/sharpener.rb b/src/sharpener.rb index 95aec6b..5bf4e36 100755 --- a/src/sharpener.rb +++ b/src/sharpener.rb @@ -6,6 +6,10 @@ $duplicates_increment = 0 $files_increment = 0 +## +# Logs progress finding duplicates to stdout. +# +# @param is_duplicate A boolean indicating if the progress to be logged includes a duplicate file or not. def log_duplicate_progress(is_duplicate:) $duplicates_increment += 1 if is_duplicate @@ -13,6 +17,12 @@ def log_duplicate_progress(is_duplicate:) $files_increment += 1 end +## +# Finds all duplicates—recursively—within the supplied target directory. Ignores any directories or files that are +# prefixed with a period character. +# +# @param target The string that represents the path to the target directory. +# def find_dupes(target) duplicates = {} @@ -20,25 +30,30 @@ def find_dupes(target) Find.prune if File.basename(path).start_with?(".") if FileTest.file?(path) - dgst = OpenSSL::Digest::SHA256.file(path).hexdigest + digest = OpenSSL::Digest::SHA256.file(path).hexdigest - log_duplicate_progress(is_duplicate: duplicates.key?(dgst)) + log_duplicate_progress(is_duplicate: duplicates.key?(digest)) - duplicates[dgst] = [] unless duplicates.key?(dgst) - duplicates[dgst] << path + duplicates[digest] = [] unless duplicates.key?(digest) + duplicates[digest] << path end end - puts "\n===" + STDOUT.puts "\n===" duplicates.select { |k, v| v.size > 1 }.each do |k, v| - puts "duplicate: #{k}" - puts v + STDOUT.puts "duplicate: #{k}" + STDOUT.puts "#{v}" end end -def find_unqiues(source, target) - -end +## +# Given a source directory, find all files in source directory that are not present in the target directory. Ignores any +# directories or files that are prefixed with a period character. +# +# @param source +# @param target +# +def find_unqiues(source, target); end case ARGV[0] when "duplicates"