Class: Omnizip::Temp::SafeExtract

Inherits:
Object
  • Object
show all
Defined in:
lib/omnizip/temp/safe_extract.rb

Overview

Safe extraction with atomic move to destination Provides rollback capability on failure

Defined Under Namespace

Classes: VerificationError

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(archive_path, dest_path) ⇒ SafeExtract

Create new safe extractor

Parameters:

  • archive_path (String)

    Path to archive

  • dest_path (String)

    Destination path



19
20
21
22
# File 'lib/omnizip/temp/safe_extract.rb', line 19

def initialize(archive_path, dest_path)
  @archive_path = archive_path
  @dest_path = dest_path
end

Instance Attribute Details

#archive_pathObject (readonly)

Returns the value of attribute archive_path.



14
15
16
# File 'lib/omnizip/temp/safe_extract.rb', line 14

def archive_path
  @archive_path
end

#dest_pathObject (readonly)

Returns the value of attribute dest_path.



14
15
16
# File 'lib/omnizip/temp/safe_extract.rb', line 14

def dest_path
  @dest_path
end

Class Method Details

.extract_safe(archive_path, dest_path) {|temp_dir| ... } ⇒ String

Class method for quick safe extraction

Parameters:

  • archive_path (String)

    Archive to extract

  • dest_path (String)

    Destination

Yields:

  • (temp_dir)

    Verification block

Returns:

  • (String)

    Destination path



75
76
77
# File 'lib/omnizip/temp/safe_extract.rb', line 75

def self.extract_safe(archive_path, dest_path, &block)
  new(archive_path, dest_path).extract(&block)
end

Instance Method Details

#extract {|temp_dir| ... } ⇒ String

Extract safely with verification

Yields:

  • (temp_dir)

    Block for verification (return truthy to proceed)

Returns:

  • (String)

    Destination path



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/omnizip/temp/safe_extract.rb', line 27

def extract
  unless File.exist?(@archive_path)
    raise Errno::ENOENT, "Archive not found: #{@archive_path}"
  end

  Dir.mktmpdir("omniz_extract_") do |temp_dir|
    # Extract to temp directory
    extract_to_temp(temp_dir)

    # User verification if block given
    if block_given?
      result = yield(temp_dir)
      unless result
        raise VerificationError, "Extraction verification failed"
      end
    end

    # Atomic move to destination
    move_to_destination(temp_dir)
  end

  @dest_path
end

#extract_verified(expected_checksums) ⇒ String

Extract with checksum verification

Parameters:

  • expected_checksums (Hash)

    Map of filename => CRC32

Returns:

  • (String)

    Destination path



54
55
56
57
58
# File 'lib/omnizip/temp/safe_extract.rb', line 54

def extract_verified(expected_checksums)
  extract do |temp_dir|
    verify_checksums(temp_dir, expected_checksums)
  end
end

#extract_with_count(expected_count) ⇒ String

Extract with file count verification

Parameters:

  • expected_count (Integer)

    Expected number of files

Returns:

  • (String)

    Destination path



63
64
65
66
67
68
# File 'lib/omnizip/temp/safe_extract.rb', line 63

def extract_with_count(expected_count)
  extract do |temp_dir|
    actual_count = count_files(temp_dir)
    actual_count == expected_count
  end
end