crush-rb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/bin/crush +138 -0
  3. 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: []