Extract `FileSystem::Dir` from the main filesystem file.
This commit is contained in:
parent
239baef845
commit
a1c9b63e61
|
@ -77,6 +77,7 @@ Style/IfUnlessModifier:
|
|||
- 'lib/zip/entry.rb'
|
||||
- 'lib/zip/file.rb'
|
||||
- 'lib/zip/filesystem.rb'
|
||||
- 'lib/zip/filesystem/dir.rb'
|
||||
- 'lib/zip/pass_thru_decompressor.rb'
|
||||
- 'lib/zip/streamable_stream.rb'
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
require 'zip'
|
||||
require_relative 'filesystem/zip_file_name_mapper'
|
||||
require_relative 'filesystem/directory_iterator'
|
||||
require_relative 'filesystem/dir'
|
||||
|
||||
module Zip
|
||||
# The ZipFileSystem API provides an API for accessing entries in
|
||||
|
@ -40,13 +41,13 @@ module Zip
|
|||
module FileSystem
|
||||
def initialize # :nodoc:
|
||||
mapped_zip = ZipFileNameMapper.new(self)
|
||||
@zip_fs_dir = ZipFsDir.new(mapped_zip)
|
||||
@zip_fs_dir = Dir.new(mapped_zip)
|
||||
@zip_fs_file = ZipFsFile.new(mapped_zip)
|
||||
@zip_fs_dir.file = @zip_fs_file
|
||||
@zip_fs_file.dir = @zip_fs_dir
|
||||
end
|
||||
|
||||
# Returns a ZipFsDir which is much like ruby's builtin Dir (class)
|
||||
# Returns a FileSystem::Dir which is much like ruby's builtin Dir (class)
|
||||
# object, except it works on the Zip::File on which this method is
|
||||
# invoked
|
||||
def dir
|
||||
|
@ -428,93 +429,6 @@ module Zip
|
|||
@mapped_zip.expand_path(path)
|
||||
end
|
||||
end
|
||||
|
||||
# Instances of this class are normally accessed via the accessor
|
||||
# ZipFile::dir. An instance of ZipFsDir behaves like ruby's
|
||||
# builtin Dir (class) object, except it works on ZipFile entries.
|
||||
#
|
||||
# The individual methods are not documented due to their
|
||||
# similarity with the methods in Dir
|
||||
class ZipFsDir
|
||||
def initialize(mapped_zip)
|
||||
@mapped_zip = mapped_zip
|
||||
end
|
||||
|
||||
attr_writer :file
|
||||
|
||||
def new(directory_name)
|
||||
DirectoryIterator.new(entries(directory_name))
|
||||
end
|
||||
|
||||
def open(directory_name)
|
||||
dir_iter = new(directory_name)
|
||||
if block_given?
|
||||
begin
|
||||
yield(dir_iter)
|
||||
return nil
|
||||
ensure
|
||||
dir_iter.close
|
||||
end
|
||||
end
|
||||
dir_iter
|
||||
end
|
||||
|
||||
def pwd
|
||||
@mapped_zip.pwd
|
||||
end
|
||||
alias getwd pwd
|
||||
|
||||
def chdir(directory_name)
|
||||
unless @file.stat(directory_name).directory?
|
||||
raise Errno::EINVAL, "Invalid argument - #{directory_name}"
|
||||
end
|
||||
|
||||
@mapped_zip.pwd = @file.expand_path(directory_name)
|
||||
end
|
||||
|
||||
def entries(directory_name)
|
||||
entries = []
|
||||
foreach(directory_name) { |e| entries << e }
|
||||
entries
|
||||
end
|
||||
|
||||
def glob(*args, &block)
|
||||
@mapped_zip.glob(*args, &block)
|
||||
end
|
||||
|
||||
def foreach(directory_name)
|
||||
unless @file.stat(directory_name).directory?
|
||||
raise Errno::ENOTDIR, directory_name
|
||||
end
|
||||
|
||||
path = @file.expand_path(directory_name)
|
||||
path << '/' unless path.end_with?('/')
|
||||
path = Regexp.escape(path)
|
||||
subdir_entry_regex = Regexp.new("^#{path}([^/]+)$")
|
||||
@mapped_zip.each do |filename|
|
||||
match = subdir_entry_regex.match(filename)
|
||||
yield(match[1]) unless match.nil?
|
||||
end
|
||||
end
|
||||
|
||||
def delete(entry_name)
|
||||
unless @file.stat(entry_name).directory?
|
||||
raise Errno::EINVAL, "Invalid argument - #{entry_name}"
|
||||
end
|
||||
|
||||
@mapped_zip.remove(entry_name)
|
||||
end
|
||||
alias rmdir delete
|
||||
alias unlink delete
|
||||
|
||||
def mkdir(entry_name, permissions = 0o755)
|
||||
@mapped_zip.mkdir(entry_name, permissions)
|
||||
end
|
||||
|
||||
def chroot(*_args)
|
||||
raise NotImplementedError, 'The chroot() function is not implemented'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class File
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Zip
|
||||
module FileSystem
|
||||
class Dir # :nodoc:all
|
||||
def initialize(mapped_zip)
|
||||
@mapped_zip = mapped_zip
|
||||
end
|
||||
|
||||
attr_writer :file
|
||||
|
||||
def new(directory_name)
|
||||
DirectoryIterator.new(entries(directory_name))
|
||||
end
|
||||
|
||||
def open(directory_name)
|
||||
dir_iter = new(directory_name)
|
||||
if block_given?
|
||||
begin
|
||||
yield(dir_iter)
|
||||
return nil
|
||||
ensure
|
||||
dir_iter.close
|
||||
end
|
||||
end
|
||||
dir_iter
|
||||
end
|
||||
|
||||
def pwd
|
||||
@mapped_zip.pwd
|
||||
end
|
||||
alias getwd pwd
|
||||
|
||||
def chdir(directory_name)
|
||||
unless @file.stat(directory_name).directory?
|
||||
raise Errno::EINVAL, "Invalid argument - #{directory_name}"
|
||||
end
|
||||
|
||||
@mapped_zip.pwd = @file.expand_path(directory_name)
|
||||
end
|
||||
|
||||
def entries(directory_name)
|
||||
entries = []
|
||||
foreach(directory_name) { |e| entries << e }
|
||||
entries
|
||||
end
|
||||
|
||||
def glob(*args, &block)
|
||||
@mapped_zip.glob(*args, &block)
|
||||
end
|
||||
|
||||
def foreach(directory_name)
|
||||
unless @file.stat(directory_name).directory?
|
||||
raise Errno::ENOTDIR, directory_name
|
||||
end
|
||||
|
||||
path = @file.expand_path(directory_name)
|
||||
path << '/' unless path.end_with?('/')
|
||||
path = Regexp.escape(path)
|
||||
subdir_entry_regex = Regexp.new("^#{path}([^/]+)$")
|
||||
@mapped_zip.each do |filename|
|
||||
match = subdir_entry_regex.match(filename)
|
||||
yield(match[1]) unless match.nil?
|
||||
end
|
||||
end
|
||||
|
||||
def delete(entry_name)
|
||||
unless @file.stat(entry_name).directory?
|
||||
raise Errno::EINVAL, "Invalid argument - #{entry_name}"
|
||||
end
|
||||
|
||||
@mapped_zip.remove(entry_name)
|
||||
end
|
||||
alias rmdir delete
|
||||
alias unlink delete
|
||||
|
||||
def mkdir(entry_name, permissions = 0o755)
|
||||
@mapped_zip.mkdir(entry_name, permissions)
|
||||
end
|
||||
|
||||
def chroot(*_args)
|
||||
raise NotImplementedError, 'The chroot() function is not implemented'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
module Zip
|
||||
module FileSystem
|
||||
# All access to Zip::File from ZipFsFile and ZipFsDir goes through a
|
||||
# ZipFileNameMapper, which has one responsibility: ensure
|
||||
# All access to Zip::File from ZipFsFile and FileSystem::Dir goes through
|
||||
# a ZipFileNameMapper, which has one responsibility: ensure
|
||||
class ZipFileNameMapper # :nodoc:all
|
||||
include Enumerable
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require 'test_helper'
|
||||
require 'zip/filesystem'
|
||||
|
||||
class ZipFsDirectoryTest < MiniTest::Test
|
||||
class DirectoryTest < MiniTest::Test
|
||||
TEST_ZIP = 'test/data/generated/zipWithDirs_copy.zip'
|
||||
GLOB_TEST_ZIP = 'test/data/globTest.zip'
|
||||
|
Loading…
Reference in New Issue