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/entry.rb'
|
||||||
- 'lib/zip/file.rb'
|
- 'lib/zip/file.rb'
|
||||||
- 'lib/zip/filesystem.rb'
|
- 'lib/zip/filesystem.rb'
|
||||||
|
- 'lib/zip/filesystem/dir.rb'
|
||||||
- 'lib/zip/pass_thru_decompressor.rb'
|
- 'lib/zip/pass_thru_decompressor.rb'
|
||||||
- 'lib/zip/streamable_stream.rb'
|
- 'lib/zip/streamable_stream.rb'
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
require 'zip'
|
require 'zip'
|
||||||
require_relative 'filesystem/zip_file_name_mapper'
|
require_relative 'filesystem/zip_file_name_mapper'
|
||||||
require_relative 'filesystem/directory_iterator'
|
require_relative 'filesystem/directory_iterator'
|
||||||
|
require_relative 'filesystem/dir'
|
||||||
|
|
||||||
module Zip
|
module Zip
|
||||||
# The ZipFileSystem API provides an API for accessing entries in
|
# The ZipFileSystem API provides an API for accessing entries in
|
||||||
|
@ -40,13 +41,13 @@ module Zip
|
||||||
module FileSystem
|
module FileSystem
|
||||||
def initialize # :nodoc:
|
def initialize # :nodoc:
|
||||||
mapped_zip = ZipFileNameMapper.new(self)
|
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_file = ZipFsFile.new(mapped_zip)
|
||||||
@zip_fs_dir.file = @zip_fs_file
|
@zip_fs_dir.file = @zip_fs_file
|
||||||
@zip_fs_file.dir = @zip_fs_dir
|
@zip_fs_file.dir = @zip_fs_dir
|
||||||
end
|
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
|
# object, except it works on the Zip::File on which this method is
|
||||||
# invoked
|
# invoked
|
||||||
def dir
|
def dir
|
||||||
|
@ -428,93 +429,6 @@ module Zip
|
||||||
@mapped_zip.expand_path(path)
|
@mapped_zip.expand_path(path)
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
||||||
class File
|
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 Zip
|
||||||
module FileSystem
|
module FileSystem
|
||||||
# All access to Zip::File from ZipFsFile and ZipFsDir goes through a
|
# All access to Zip::File from ZipFsFile and FileSystem::Dir goes through
|
||||||
# ZipFileNameMapper, which has one responsibility: ensure
|
# a ZipFileNameMapper, which has one responsibility: ensure
|
||||||
class ZipFileNameMapper # :nodoc:all
|
class ZipFileNameMapper # :nodoc:all
|
||||||
include Enumerable
|
include Enumerable
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
require 'test_helper'
|
require 'test_helper'
|
||||||
require 'zip/filesystem'
|
require 'zip/filesystem'
|
||||||
|
|
||||||
class ZipFsDirectoryTest < MiniTest::Test
|
class DirectoryTest < MiniTest::Test
|
||||||
TEST_ZIP = 'test/data/generated/zipWithDirs_copy.zip'
|
TEST_ZIP = 'test/data/generated/zipWithDirs_copy.zip'
|
||||||
GLOB_TEST_ZIP = 'test/data/globTest.zip'
|
GLOB_TEST_ZIP = 'test/data/globTest.zip'
|
||||||
|
|
Loading…
Reference in New Issue