omnizip 0.3.9 → 0.3.10

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.
Files changed (182) hide show
  1. checksums.yaml +4 -4
  2. data/TODO.refactor/00-overview.md +67 -0
  3. data/TODO.refactor/01-registry-base-class.md +81 -0
  4. data/TODO.refactor/02-error-hierarchy.md +57 -0
  5. data/TODO.refactor/03-autoload-entry-point.md +69 -0
  6. data/TODO.refactor/04-filter-base-consolidation.md +49 -0
  7. data/TODO.refactor/05-send-private-methods.md +64 -0
  8. data/TODO.refactor/06-instance-variable-access.md +69 -0
  9. data/TODO.refactor/07-respond-to-replacement.md +91 -0
  10. data/TODO.refactor/08-spec-doubles.md +27 -0
  11. data/TODO.refactor/09-cli-shared-module.md +35 -0
  12. data/TODO.refactor/10-format-detector-ocp.md +34 -0
  13. data/TODO.refactor/11-convenience-decoupling.md +38 -0
  14. data/TODO.refactor/12-thread-safety.md +8 -0
  15. data/TODO.refactor/13-lutaml-model-migration.md +82 -0
  16. data/TODO.refactor/14-add-missing-specs.md +25 -0
  17. data/lib/omnizip/algorithm.rb +0 -2
  18. data/lib/omnizip/algorithm_registry.rb +29 -57
  19. data/lib/omnizip/algorithms/lzma/dictionary.rb +4 -3
  20. data/lib/omnizip/algorithms/lzma/lzip_decoder.rb +2 -0
  21. data/lib/omnizip/algorithms/lzma/range_decoder.rb +1 -1
  22. data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +6 -5
  23. data/lib/omnizip/algorithms/lzma2/encoder.rb +0 -2
  24. data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +0 -2
  25. data/lib/omnizip/algorithms/lzma2/properties.rb +0 -2
  26. data/lib/omnizip/algorithms/ppmd7/model.rb +1 -1
  27. data/lib/omnizip/algorithms/ppmd8/context.rb +0 -2
  28. data/lib/omnizip/algorithms/ppmd8/model.rb +1 -1
  29. data/lib/omnizip/algorithms/ppmd8.rb +0 -2
  30. data/lib/omnizip/algorithms/ppmd_base.rb +0 -2
  31. data/lib/omnizip/algorithms/sevenzip_lzma2.rb +0 -5
  32. data/lib/omnizip/algorithms/xz_lzma2.rb +0 -5
  33. data/lib/omnizip/algorithms/zstandard/frame/header.rb +3 -5
  34. data/lib/omnizip/algorithms.rb +1 -0
  35. data/lib/omnizip/archive_handler.rb +75 -0
  36. data/lib/omnizip/archive_handlers/tar_handler.rb +51 -0
  37. data/lib/omnizip/archive_handlers/zip_handler.rb +73 -0
  38. data/lib/omnizip/archive_handlers.rb +11 -0
  39. data/lib/omnizip/checksum_registry.rb +23 -96
  40. data/lib/omnizip/cli/shared.rb +31 -0
  41. data/lib/omnizip/cli.rb +6 -43
  42. data/lib/omnizip/commands/archive_create_command.rb +0 -6
  43. data/lib/omnizip/commands/archive_extract_command.rb +0 -4
  44. data/lib/omnizip/commands/archive_list_command.rb +0 -4
  45. data/lib/omnizip/commands/archive_repair_command.rb +0 -2
  46. data/lib/omnizip/commands/archive_verify_command.rb +0 -2
  47. data/lib/omnizip/commands/compress_command.rb +0 -2
  48. data/lib/omnizip/commands/decompress_command.rb +0 -2
  49. data/lib/omnizip/commands/list_command.rb +0 -2
  50. data/lib/omnizip/commands/metadata_command.rb +0 -5
  51. data/lib/omnizip/commands/parity_create_command.rb +0 -2
  52. data/lib/omnizip/commands/parity_repair_command.rb +0 -2
  53. data/lib/omnizip/commands/parity_verify_command.rb +0 -2
  54. data/lib/omnizip/commands/profile_list_command.rb +0 -2
  55. data/lib/omnizip/commands/profile_show_command.rb +0 -2
  56. data/lib/omnizip/convenience.rb +111 -234
  57. data/lib/omnizip/converter/seven_zip_to_zip_strategy.rb +1 -1
  58. data/lib/omnizip/crypto/aes256/cipher.rb +6 -1
  59. data/lib/omnizip/error.rb +22 -18
  60. data/lib/omnizip/filter.rb +5 -3
  61. data/lib/omnizip/filter_registry.rb +74 -98
  62. data/lib/omnizip/filters/bcj2.rb +0 -2
  63. data/lib/omnizip/filters/bcj_x86.rb +0 -2
  64. data/lib/omnizip/filters/filter_base.rb +4 -70
  65. data/lib/omnizip/filters/registry.rb +0 -2
  66. data/lib/omnizip/format_detector.rb +21 -12
  67. data/lib/omnizip/format_registry.rb +69 -53
  68. data/lib/omnizip/formats/bzip2_file.rb +0 -2
  69. data/lib/omnizip/formats/cpio/entry.rb +0 -2
  70. data/lib/omnizip/formats/cpio/reader.rb +0 -1
  71. data/lib/omnizip/formats/cpio/writer.rb +0 -1
  72. data/lib/omnizip/formats/cpio.rb +0 -1
  73. data/lib/omnizip/formats/format_spec_loader.rb +1 -1
  74. data/lib/omnizip/formats/gzip.rb +0 -2
  75. data/lib/omnizip/formats/iso/directory_record.rb +6 -3
  76. data/lib/omnizip/formats/iso/reader.rb +2 -2
  77. data/lib/omnizip/formats/iso.rb +0 -1
  78. data/lib/omnizip/formats/lzip.rb +5 -25
  79. data/lib/omnizip/formats/lzma_alone.rb +7 -25
  80. data/lib/omnizip/formats/msi/reader.rb +1 -0
  81. data/lib/omnizip/formats/msi/string_pool.rb +2 -3
  82. data/lib/omnizip/formats/msi.rb +1 -4
  83. data/lib/omnizip/formats/ole/allocation_table.rb +0 -1
  84. data/lib/omnizip/formats/ole/dirent.rb +9 -4
  85. data/lib/omnizip/formats/ole/header.rb +0 -1
  86. data/lib/omnizip/formats/ole/ranges_io.rb +1 -1
  87. data/lib/omnizip/formats/ole/storage.rb +5 -6
  88. data/lib/omnizip/formats/ole.rb +0 -1
  89. data/lib/omnizip/formats/rar/block_parser.rb +0 -1
  90. data/lib/omnizip/formats/rar/compression/ppmd/encoder.rb +1 -1
  91. data/lib/omnizip/formats/rar/decompressor.rb +1 -0
  92. data/lib/omnizip/formats/rar/header.rb +0 -1
  93. data/lib/omnizip/formats/rar/rar5/writer.rb +0 -3
  94. data/lib/omnizip/formats/rar/reader.rb +2 -3
  95. data/lib/omnizip/formats/rar/writer.rb +0 -1
  96. data/lib/omnizip/formats/rar.rb +0 -1
  97. data/lib/omnizip/formats/rpm/entry.rb +0 -1
  98. data/lib/omnizip/formats/rpm/header.rb +1 -6
  99. data/lib/omnizip/formats/rpm/lead.rb +37 -26
  100. data/lib/omnizip/formats/rpm/tag.rb +0 -1
  101. data/lib/omnizip/formats/rpm/writer.rb +0 -1
  102. data/lib/omnizip/formats/seven_zip/bcj2_stream_decompressor.rb +0 -1
  103. data/lib/omnizip/formats/seven_zip/coder_chain.rb +1 -2
  104. data/lib/omnizip/formats/seven_zip/encoded_header.rb +0 -1
  105. data/lib/omnizip/formats/seven_zip/encrypted_header.rb +0 -1
  106. data/lib/omnizip/formats/seven_zip/header.rb +0 -1
  107. data/lib/omnizip/formats/seven_zip/header_encryptor.rb +0 -1
  108. data/lib/omnizip/formats/seven_zip/header_writer.rb +0 -1
  109. data/lib/omnizip/formats/seven_zip/models/file_entry.rb +1 -1
  110. data/lib/omnizip/formats/seven_zip/parser.rb +1 -2
  111. data/lib/omnizip/formats/seven_zip/reader.rb +13 -2
  112. data/lib/omnizip/formats/seven_zip/split_archive_reader.rb +0 -1
  113. data/lib/omnizip/formats/seven_zip/split_archive_writer.rb +0 -1
  114. data/lib/omnizip/formats/seven_zip/writer.rb +4 -6
  115. data/lib/omnizip/formats/seven_zip.rb +2 -4
  116. data/lib/omnizip/formats/tar/entry.rb +0 -2
  117. data/lib/omnizip/formats/tar/header.rb +0 -2
  118. data/lib/omnizip/formats/tar/reader.rb +0 -2
  119. data/lib/omnizip/formats/tar/writer.rb +0 -2
  120. data/lib/omnizip/formats/tar.rb +0 -1
  121. data/lib/omnizip/formats/xar/entry.rb +0 -1
  122. data/lib/omnizip/formats/xar/header.rb +0 -1
  123. data/lib/omnizip/formats/xar/reader.rb +0 -1
  124. data/lib/omnizip/formats/xar/toc.rb +1 -2
  125. data/lib/omnizip/formats/xar/writer.rb +11 -3
  126. data/lib/omnizip/formats/xar.rb +0 -1
  127. data/lib/omnizip/formats/xz/reader.rb +7 -3
  128. data/lib/omnizip/formats/xz.rb +3 -40
  129. data/lib/omnizip/formats/xz_impl/block_decoder.rb +4 -10
  130. data/lib/omnizip/formats/xz_impl/block_encoder.rb +0 -2
  131. data/lib/omnizip/formats/xz_impl/block_header_parser.rb +0 -2
  132. data/lib/omnizip/formats/xz_impl/index_decoder.rb +0 -1
  133. data/lib/omnizip/formats/xz_impl/index_encoder.rb +0 -1
  134. data/lib/omnizip/formats/xz_impl/stream_encoder.rb +1 -1
  135. data/lib/omnizip/formats/xz_impl/stream_footer.rb +0 -1
  136. data/lib/omnizip/formats/xz_impl/stream_footer_parser.rb +0 -1
  137. data/lib/omnizip/formats/xz_impl/stream_header.rb +0 -1
  138. data/lib/omnizip/formats/xz_impl/stream_header_parser.rb +0 -2
  139. data/lib/omnizip/formats/zip/central_directory_header.rb +2 -3
  140. data/lib/omnizip/formats/zip/end_of_central_directory.rb +0 -2
  141. data/lib/omnizip/formats/zip/local_file_header.rb +0 -2
  142. data/lib/omnizip/formats/zip/reader.rb +12 -2
  143. data/lib/omnizip/formats/zip/writer.rb +73 -1
  144. data/lib/omnizip/formats/zip/zip64_end_of_central_directory.rb +0 -2
  145. data/lib/omnizip/formats/zip/zip64_end_of_central_directory_locator.rb +0 -2
  146. data/lib/omnizip/formats/zip/zip64_extra_field.rb +0 -2
  147. data/lib/omnizip/formats/zip.rb +0 -1
  148. data/lib/omnizip/formats.rb +8 -24
  149. data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +2 -2
  150. data/lib/omnizip/implementations/seven_zip/lzma/range_encoder.rb +1 -1
  151. data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +0 -6
  152. data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +3 -4
  153. data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +0 -1
  154. data/lib/omnizip/io/source.rb +136 -0
  155. data/lib/omnizip/io.rb +2 -0
  156. data/lib/omnizip/link_handler.rb +7 -3
  157. data/lib/omnizip/metadata/metadata_editor.rb +1 -1
  158. data/lib/omnizip/models/algorithm_metadata.rb +33 -60
  159. data/lib/omnizip/models/compression_options.rb +40 -53
  160. data/lib/omnizip/models/conversion_options.rb +9 -18
  161. data/lib/omnizip/models/parallel_options.rb +25 -0
  162. data/lib/omnizip/optimization_registry.rb +8 -44
  163. data/lib/omnizip/parallel/job_scheduler.rb +26 -8
  164. data/lib/omnizip/parallel/parallel_compressor.rb +10 -20
  165. data/lib/omnizip/parallel/parallel_extractor.rb +20 -11
  166. data/lib/omnizip/parity/par2_repairer.rb +5 -5
  167. data/lib/omnizip/parity/par2_verifier.rb +27 -22
  168. data/lib/omnizip/parity.rb +4 -4
  169. data/lib/omnizip/password/encryption_registry.rb +11 -50
  170. data/lib/omnizip/password/zip_crypto_strategy.rb +1 -4
  171. data/lib/omnizip/pipe/stream_decompressor.rb +2 -3
  172. data/lib/omnizip/profile/archive_profile.rb +0 -2
  173. data/lib/omnizip/profile/binary_profile.rb +0 -2
  174. data/lib/omnizip/profile/compression_profile.rb +0 -1
  175. data/lib/omnizip/profile/profile_detector.rb +0 -2
  176. data/lib/omnizip/profile/text_profile.rb +0 -2
  177. data/lib/omnizip/profile.rb +0 -2
  178. data/lib/omnizip/registry.rb +112 -0
  179. data/lib/omnizip/version.rb +1 -1
  180. data/lib/omnizip/zip/file.rb +20 -9
  181. data/lib/omnizip.rb +26 -58
  182. metadata +24 -2
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module ArchiveHandlers
5
+ # Adapter that exposes the canonical +create+/+open+/+extract_to+
6
+ # /+list+ interface for the ZIP format. Wraps +Omnizip::Zip::File+.
7
+ class ZipHandler
8
+ def create(path, &block)
9
+ Omnizip::Zip::File.create(path, &block)
10
+ end
11
+
12
+ def open(path, &block)
13
+ Omnizip::Zip::File.open(path, &block)
14
+ end
15
+
16
+ def extract_to(path, output_dir, overwrite: false, **_)
17
+ extracted = []
18
+ Omnizip::Zip::File.open(path) do |zip|
19
+ zip.each do |entry|
20
+ dest_path = ::File.join(output_dir, entry.name)
21
+ on_exists = if overwrite
22
+ proc { true }
23
+ else
24
+ proc { |_e, p| raise "File exists: #{p}" }
25
+ end
26
+ zip.extract(entry, dest_path, &on_exists)
27
+ extracted << dest_path
28
+ end
29
+ end
30
+ extracted
31
+ end
32
+
33
+ def list(path, details: false, **_)
34
+ Omnizip::Zip::File.open(path) do |zip|
35
+ if details
36
+ zip.entries.map do |entry|
37
+ {
38
+ name: entry.name,
39
+ size: entry.size,
40
+ compressed_size: entry.compressed_size,
41
+ compression_method: entry.compression_method,
42
+ crc: entry.crc,
43
+ time: entry.time,
44
+ directory: entry.directory?,
45
+ }
46
+ end
47
+ else
48
+ zip.names
49
+ end
50
+ end
51
+ end
52
+
53
+ def read_entry(path, entry_name)
54
+ Omnizip::Zip::File.open(path) do |zip|
55
+ entry = zip.get_entry(entry_name)
56
+ raise Errno::ENOENT, "Entry not found: #{entry_name}" unless entry
57
+
58
+ zip.read(entry)
59
+ end
60
+ end
61
+
62
+ def add_entry(path, entry_name, source_path)
63
+ Omnizip::Zip::File.open(path) { |zip| zip.add(entry_name, source_path) }
64
+ end
65
+
66
+ def remove_entry(path, entry_name)
67
+ Omnizip::Zip::File.open(path) { |zip| zip.remove(entry_name) }
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ Omnizip::ArchiveHandler.register(:zip, Omnizip::ArchiveHandlers::ZipHandler.new)
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ # Archive handler namespace. Each format ships a Handler class here
5
+ # that adapts its format-specific API to the canonical contract
6
+ # documented on +Omnizip::ArchiveHandler+.
7
+ module ArchiveHandlers
8
+ autoload :ZipHandler, "omnizip/archive_handlers/zip_handler"
9
+ autoload :TarHandler, "omnizip/archive_handlers/tar_handler"
10
+ end
11
+ end
@@ -1,114 +1,41 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- #
4
- # Copyright (C) 2024 Ribose Inc.
5
- #
6
- # This file is part of Omnizip.
7
- #
8
- # Omnizip is a pure Ruby port of 7-Zip compression algorithms.
9
- # Based on the 7-Zip LZMA SDK by Igor Pavlov.
10
- #
11
- # This library is free software; you can redistribute it and/or
12
- # modify it under the terms of the GNU Lesser General Public
13
- # License as published by the Free Software Foundation; either
14
- # version 2.1 of the License, or (at your option) any later version.
15
- #
16
- # See the COPYING file for the complete text of the license.
17
- #
18
-
19
3
  module Omnizip
20
- # Registry for managing available checksum algorithms.
21
- #
22
- # This class maintains a central registry of all checksum implementations
23
- # available in Omnizip, providing a consistent interface for algorithm
24
- # discovery and instantiation.
25
- #
26
- # The registry pattern ensures that checksum algorithms are defined in
27
- # one place and can be easily extended with new implementations without
28
- # modifying existing code.
29
- #
30
- # @example Register a new checksum algorithm
31
- # ChecksumRegistry.register(:crc32, Omnizip::Checksums::Crc32)
32
- #
33
- # @example Get a checksum class
34
- # crc_class = ChecksumRegistry.get(:crc32)
35
- # checksum = crc_class.calculate("data")
36
- #
37
- # @example List available checksums
38
- # ChecksumRegistry.available
39
- # # => [:crc32, :crc64]
40
- class ChecksumRegistry
41
- @checksums = {}
4
+ class ChecksumRegistry < Omnizip::Registry
5
+ BUILTIN_CHECKSUMS = {
6
+ crc32: "Omnizip::Checksums::Crc32",
7
+ crc64: "Omnizip::Checksums::Crc64",
8
+ }.freeze
42
9
 
43
10
  class << self
44
- # Register a checksum algorithm.
45
- #
46
- # Adds a new checksum implementation to the registry, making it
47
- # available for use throughout the application.
48
- #
49
- # @param name [Symbol] unique identifier for the checksum
50
- # @param checksum_class [Class] class implementing the checksum
51
- # @return [void]
52
- # @raise [ArgumentError] if name is already registered
53
- def register(name, checksum_class)
54
- name = name.to_sym
55
- if @checksums.key?(name)
56
- raise ArgumentError,
57
- "Checksum '#{name}' is already registered"
58
- end
59
-
60
- @checksums[name] = checksum_class
11
+ def not_found_error_class
12
+ Omnizip::UnknownChecksumError
61
13
  end
62
14
 
63
- # Retrieve a checksum class by name.
64
- #
65
- # Returns the checksum class registered under the given name,
66
- # allowing for instantiation and use.
67
- #
68
- # @param name [Symbol] identifier of the checksum to retrieve
69
- # @return [Class] the checksum class
70
- # @raise [UnknownAlgorithmError] if checksum not found
71
- def get(name)
72
- name = name.to_sym
73
- checksum_class = @checksums[name]
15
+ def label
16
+ "Checksum"
17
+ end
74
18
 
75
- unless checksum_class
76
- raise UnknownAlgorithmError,
77
- "Unknown checksum: '#{name}'. Available: " \
78
- "#{available.join(', ')}"
19
+ def register(name, checksum_class)
20
+ key = normalize_key(name)
21
+ existing = storage[key]
22
+ if existing && existing != checksum_class
23
+ raise ArgumentError, "Checksum '#{key}' is already registered"
79
24
  end
80
25
 
26
+ synchronize { storage[key] = checksum_class }
81
27
  checksum_class
82
28
  end
83
29
 
84
- # List all available checksum algorithms.
85
- #
86
- # Returns an array of registered checksum names, useful for
87
- # displaying options to users or validating input.
88
- #
89
- # @return [Array<Symbol>] array of registered checksum names
90
30
  def available
91
- @checksums.keys.sort
92
- end
93
-
94
- # Check if a checksum is registered.
95
- #
96
- # @param name [Symbol] identifier of the checksum to check
97
- # @return [Boolean] true if registered, false otherwise
98
- def registered?(name)
99
- @checksums.key?(name.to_sym)
100
- end
101
-
102
- # Clear all registered checksums.
103
- #
104
- # This method is primarily for testing purposes and should not
105
- # be used in production code.
106
- #
107
- # @return [void]
108
- # @api private
109
- def clear
110
- @checksums.clear
31
+ super.sort
111
32
  end
112
33
  end
113
34
  end
114
35
  end
36
+
37
+ Omnizip::ChecksumRegistry::BUILTIN_CHECKSUMS.each do |name, const_path|
38
+ Omnizip::ChecksumRegistry.register_lazy(name) do
39
+ Omnizip::ChecksumRegistry.register(name, Object.const_get(const_path))
40
+ end
41
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ class Cli
5
+ # Shared helpers used by the Thor command groups defined in
6
+ # lib/omnizip/cli.rb (ProfileCommands, ArchiveCommands, Cli).
7
+ module Shared
8
+ # Print a formatted error message and exit nonzero.
9
+ #
10
+ # @param error [StandardError] the error to display
11
+ def handle_error(error)
12
+ warn Omnizip::CliOutputFormatter.format_error(error)
13
+ exit 1
14
+ end
15
+
16
+ # Format a byte count with a binary-unit suffix.
17
+ #
18
+ # @param bytes [Integer] the byte count
19
+ # @return [String] human-readable size (e.g. "1.5 MB")
20
+ def format_bytes(bytes)
21
+ return "0 B" if bytes.zero?
22
+
23
+ units = %w[B KB MB GB TB]
24
+ exp = (Math.log(bytes) / Math.log(1024)).to_i
25
+ exp = [exp, units.size - 1].min
26
+
27
+ "%.1f %s" % [bytes.to_f / (1024**exp), units[exp]]
28
+ end
29
+ end
30
+ end
31
+ end
data/lib/omnizip/cli.rb CHANGED
@@ -17,22 +17,12 @@
17
17
  #
18
18
 
19
19
  require "thor"
20
- require "omnizip/commands/compress_command"
21
- require "omnizip/commands/decompress_command"
22
- require "omnizip/commands/list_command"
23
- require "omnizip/commands/archive_create_command"
24
- require "omnizip/commands/archive_extract_command"
25
- require "omnizip/commands/archive_list_command"
26
- require "omnizip/commands/profile_list_command"
27
- require "omnizip/commands/profile_show_command"
28
- require "omnizip/commands/metadata_command"
29
- require "omnizip/commands/archive_verify_command"
30
- require "omnizip/commands/archive_repair_command"
31
- require "omnizip/cli/output_formatter"
32
20
 
33
21
  module Omnizip
34
22
  # Profile commands subcommand group
35
23
  class ProfileCommands < Thor
24
+ include Omnizip::Cli::Shared
25
+
36
26
  class << self
37
27
  def exit_on_failure?
38
28
  true
@@ -75,17 +65,12 @@ module Omnizip
75
65
  rescue StandardError => e
76
66
  handle_error(e)
77
67
  end
78
-
79
- private
80
-
81
- def handle_error(error)
82
- warn Omnizip::CliOutputFormatter.format_error(error)
83
- exit 1
84
- end
85
68
  end
86
69
 
87
70
  # Archive commands subcommand group
88
71
  class ArchiveCommands < Thor
72
+ include Omnizip::Cli::Shared
73
+
89
74
  class << self
90
75
  def exit_on_failure?
91
76
  true
@@ -306,13 +291,6 @@ module Omnizip
306
291
  rescue StandardError => e
307
292
  handle_error(e)
308
293
  end
309
-
310
- private
311
-
312
- def handle_error(error)
313
- warn Omnizip::CliOutputFormatter.format_error(error)
314
- exit 1
315
- end
316
294
  end
317
295
 
318
296
  # Command-line interface for Omnizip.
@@ -320,6 +298,8 @@ module Omnizip
320
298
  # Provides Thor-based CLI commands for compressing and decompressing
321
299
  # files using various compression algorithms.
322
300
  class Cli < Thor
301
+ include Omnizip::Cli::Shared
302
+
323
303
  class << self
324
304
  def exit_on_failure?
325
305
  true
@@ -472,8 +452,6 @@ module Omnizip
472
452
  aliases: "-v",
473
453
  desc: "Enable verbose output"
474
454
  def convert(source, target)
475
- require "omnizip/converter"
476
-
477
455
  puts "Converting #{source} to #{target}..." if options[:verbose]
478
456
 
479
457
  result = Omnizip::Converter.convert(
@@ -553,20 +531,5 @@ module Omnizip
553
531
  ensure
554
532
  input_io.close if input_io && input != "-"
555
533
  end
556
-
557
- def handle_error(error)
558
- warn CliOutputFormatter.format_error(error)
559
- exit 1
560
- end
561
-
562
- def format_bytes(bytes)
563
- return "0 B" if bytes.zero?
564
-
565
- units = %w[B KB MB GB TB]
566
- exp = (Math.log(bytes) / Math.log(1024)).to_i
567
- exp = [exp, units.size - 1].min
568
-
569
- "%.1f %s" % [bytes.to_f / (1024**exp), units[exp]]
570
- end
571
534
  end
572
535
  end
@@ -16,9 +16,6 @@
16
16
  # See the COPYING file for the complete text of the license.
17
17
  #
18
18
 
19
- require "omnizip/cli/output_formatter"
20
- require "omnizip/formats/seven_zip/writer"
21
-
22
19
  module Omnizip
23
20
  module Commands
24
21
  # Command to create .7z archives from files and directories.
@@ -123,8 +120,6 @@ module Omnizip
123
120
 
124
121
  start_time = Time.now
125
122
 
126
- require "omnizip/formats/rar"
127
-
128
123
  writer_opts = {
129
124
  version: version,
130
125
  compression: compression,
@@ -388,7 +383,6 @@ module Omnizip
388
383
  def parse_volume_size(size_str)
389
384
  return nil if size_str.nil? || size_str.empty?
390
385
 
391
- require "omnizip/models/split_options"
392
386
  Omnizip::Models::SplitOptions.parse_volume_size(size_str)
393
387
  end
394
388
 
@@ -16,10 +16,6 @@
16
16
  # See the COPYING file for the complete text of the license.
17
17
  #
18
18
 
19
- require "omnizip/cli/output_formatter"
20
- require "omnizip/formats/seven_zip/reader"
21
- require "omnizip/extraction"
22
-
23
19
  module Omnizip
24
20
  module Commands
25
21
  # Command to extract .7z archives to a directory.
@@ -16,10 +16,6 @@
16
16
  # See the COPYING file for the complete text of the license.
17
17
  #
18
18
 
19
- require "omnizip/cli/output_formatter"
20
- require "omnizip/formats/seven_zip/reader"
21
- require "omnizip/extraction"
22
-
23
19
  module Omnizip
24
20
  module Commands
25
21
  # Command to list contents of .7z archives.
@@ -18,8 +18,6 @@ module Omnizip
18
18
  # @param input_path [String] Path to corrupted archive
19
19
  # @param output_path [String] Path for repaired archive
20
20
  def run(input_path, output_path)
21
- require "omnizip/formats/rar"
22
-
23
21
  raise "Archive not found: #{input_path}" unless File.exist?(input_path)
24
22
 
25
23
  # Detect format
@@ -17,8 +17,6 @@ module Omnizip
17
17
  #
18
18
  # @param archive_path [String] Path to archive
19
19
  def run(archive_path)
20
- require "omnizip/formats/rar"
21
-
22
20
  unless File.exist?(archive_path)
23
21
  raise "Archive not found: #{archive_path}"
24
22
  end
@@ -16,8 +16,6 @@
16
16
  # See the COPYING file for the complete text of the license.
17
17
  #
18
18
 
19
- require "omnizip/cli/output_formatter"
20
-
21
19
  module Omnizip
22
20
  module Commands
23
21
  # Command to compress files using specified algorithm.
@@ -16,8 +16,6 @@
16
16
  # See the COPYING file for the complete text of the license.
17
17
  #
18
18
 
19
- require "omnizip/cli/output_formatter"
20
-
21
19
  module Omnizip
22
20
  module Commands
23
21
  # Command to decompress files using specified algorithm.
@@ -16,8 +16,6 @@
16
16
  # See the COPYING file for the complete text of the license.
17
17
  #
18
18
 
19
- require "omnizip/cli/output_formatter"
20
-
21
19
  module Omnizip
22
20
  module Commands
23
21
  # Command to list available compression algorithms.
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "omnizip/cli/output_formatter"
4
-
5
3
  module Omnizip
6
4
  module Commands
7
5
  # Metadata command implementation
@@ -16,9 +14,6 @@ module Omnizip
16
14
  # @param archive_path [String] Path to archive
17
15
  # @param pattern [String, nil] Optional pattern to match entries
18
16
  def run(archive_path, pattern = nil)
19
- require "omnizip/zip/file"
20
- require "omnizip/metadata"
21
-
22
17
  unless File.exist?(archive_path)
23
18
  raise Errno::ENOENT, "Archive not found: #{archive_path}"
24
19
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "omnizip/parity"
4
-
5
3
  module Omnizip
6
4
  module Commands
7
5
  # Command to create PAR2 parity files
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "omnizip/parity"
4
-
5
3
  module Omnizip
6
4
  module Commands
7
5
  # Command to repair files using PAR2
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "omnizip/parity"
4
-
5
3
  module Omnizip
6
4
  module Commands
7
5
  # Command to verify files using PAR2
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "omnizip/cli/output_formatter"
4
-
5
3
  module Omnizip
6
4
  module Commands
7
5
  # Command to list available compression profiles
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "omnizip/cli/output_formatter"
4
-
5
3
  module Omnizip
6
4
  module Commands
7
5
  # Command to show details of a specific compression profile