crush-rb 0.1.0
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/bin/crush +138 -0
- metadata +46 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0d986921915063502f6e16d91852096ade00ddff463a6970ce2be18b630ca2b6
|
4
|
+
data.tar.gz: 58cb0eba18e0513c3df831a1a1aa76188923e259352478220707cb41ed9d562a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a3efb8b4698d71f3142e05ff360443ccb981358922f275e88b86a5b5fa08f4e6c8d65a5f2ceb9df93c4f14587b38279fa61eeffa754f6fc597c517c37757fdf8
|
7
|
+
data.tar.gz: a20ad3ac2b93e58a99d955382c3be501472cfbc71d49fd9144c4fd06befaac21865d636ba8b9c82ec48459b54f2c6946c42e004dbedda73f98668e5966965986
|
data/bin/crush
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'tmpdir'
|
4
|
+
|
5
|
+
VERBOSE = !%w[0 false].include?(ENV.fetch('VERBOSE', '0'))
|
6
|
+
|
7
|
+
def dbg(msg = nil)
|
8
|
+
warn(msg || yield) if VERBOSE
|
9
|
+
end
|
10
|
+
|
11
|
+
def usage!(exit_code: 0)
|
12
|
+
method(exit_code.zero? ? :puts : :warn)
|
13
|
+
.call("Usage: crush [SWITCHES] path/to/directory/to/compress\n\t-h,--help:\tShow this message")
|
14
|
+
exit(exit_code)
|
15
|
+
end
|
16
|
+
|
17
|
+
dbg { "VERBOSE=#{ENV.fetch('VERBOSE')}; verbose mode is enabled" }
|
18
|
+
|
19
|
+
usage! if %w[-h --help].any? { |help_opt| ARGV.include?(help_opt) }
|
20
|
+
usage!(exit_code: 1) unless ARGV.size == 1
|
21
|
+
|
22
|
+
source = ARGV.first
|
23
|
+
dbg("Source file/directory: #{source}")
|
24
|
+
unless File.exist?(source)
|
25
|
+
warn("File does not exist: #{source}")
|
26
|
+
exit(1)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Base class of all 3 archive options
|
30
|
+
class Archive
|
31
|
+
attr_accessor :target_directory, :source
|
32
|
+
|
33
|
+
def initialize(target_directory, source)
|
34
|
+
self.target_directory = target_directory
|
35
|
+
self.source = source
|
36
|
+
end
|
37
|
+
|
38
|
+
def basename
|
39
|
+
File.basename(source)
|
40
|
+
end
|
41
|
+
|
42
|
+
def ext
|
43
|
+
raise NotImplementedError
|
44
|
+
end
|
45
|
+
|
46
|
+
def target_file
|
47
|
+
"#{basename}.tar.#{ext}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def target_path
|
51
|
+
File.join(target_directory, target_file)
|
52
|
+
end
|
53
|
+
|
54
|
+
def compression_option
|
55
|
+
raise NotImplementedError
|
56
|
+
end
|
57
|
+
|
58
|
+
def log
|
59
|
+
File.join(target_directory, "#{ext}.log")
|
60
|
+
end
|
61
|
+
|
62
|
+
def size
|
63
|
+
File.size(target_path)
|
64
|
+
end
|
65
|
+
|
66
|
+
def compress!
|
67
|
+
dbg("[#{self.class}] Starting compression")
|
68
|
+
success = system("tar -c#{compression_option}vf #{target_path} #{source} 2> #{log}")
|
69
|
+
dbg("[#{self.class}] Compression attempt complete: #{success ? :success : :failure}")
|
70
|
+
return self if success
|
71
|
+
|
72
|
+
warn("Error compressing #{source} to #{self.class} format")
|
73
|
+
begin
|
74
|
+
warn(File.read(log))
|
75
|
+
rescue StandardError
|
76
|
+
warn("Could not read log file #{log}")
|
77
|
+
end
|
78
|
+
exit(2)
|
79
|
+
end
|
80
|
+
|
81
|
+
def move_to!(dir)
|
82
|
+
dbg("[#{self.class}] Moving #{target_path} to #{dir}")
|
83
|
+
File.rename(target_path, File.join(dir, File.basename(target_file)))
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Compress using gzip
|
88
|
+
class Gzip < Archive
|
89
|
+
def ext
|
90
|
+
:gz
|
91
|
+
end
|
92
|
+
|
93
|
+
def compression_option
|
94
|
+
:z
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Compress using gzip
|
99
|
+
class Bzip2 < Archive
|
100
|
+
def ext
|
101
|
+
:bz2
|
102
|
+
end
|
103
|
+
|
104
|
+
def compression_option
|
105
|
+
:j
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Compress using gzip
|
110
|
+
class Xz < Archive
|
111
|
+
def ext
|
112
|
+
:xz
|
113
|
+
end
|
114
|
+
|
115
|
+
def compression_option
|
116
|
+
:J
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
FORMATS = [Gzip, Bzip2, Xz].freeze
|
121
|
+
|
122
|
+
result = nil
|
123
|
+
|
124
|
+
Dir.mktmpdir do |tempdir_path|
|
125
|
+
dbg("Working in temporary directory #{tempdir_path}")
|
126
|
+
|
127
|
+
archives = FORMATS.map { |archive_class| archive_class.new(tempdir_path, source) }
|
128
|
+
|
129
|
+
threads = archives.map { |archive| Thread.new { archive.compress! } }
|
130
|
+
threads.each(&:join)
|
131
|
+
archives.each { |archive| dbg("#{archive.target_file}:\tSize=#{archive.size}") }
|
132
|
+
smallest, _others = archives.sort_by(&:size)
|
133
|
+
dbg("Keeping #{smallest.target_file}")
|
134
|
+
smallest.move_to!(Dir.pwd)
|
135
|
+
result = smallest.target_file
|
136
|
+
end
|
137
|
+
|
138
|
+
puts result
|
metadata
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: crush-rb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alexandre Ignjatovic
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-05-28 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Run several flavors of compression to keep only the most space efficient
|
14
|
+
one
|
15
|
+
email: alexnadre.ignjatovic@gmail.com
|
16
|
+
executables:
|
17
|
+
- crush
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- bin/crush
|
22
|
+
homepage: https://github.com/bankair/crush-rb
|
23
|
+
licenses:
|
24
|
+
- MIT
|
25
|
+
metadata:
|
26
|
+
source_code_uri: https://github.com/bankair/crush-rb
|
27
|
+
post_install_message:
|
28
|
+
rdoc_options: []
|
29
|
+
require_paths:
|
30
|
+
- lib
|
31
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 3.2.0
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
requirements: []
|
42
|
+
rubygems_version: 3.5.7
|
43
|
+
signing_key:
|
44
|
+
specification_version: 4
|
45
|
+
summary: Optimize your archive storage efficiency
|
46
|
+
test_files: []
|