# -*- encoding: utf-8 -*- # # Author:: Fletcher () # # Copyright (C) 2015, Fletcher Nichol # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require 'delegate' require 'pathname' require 'tempfile' require 'zip' module WinRM module FS module Core # A temporary Zip file for a given directory. # # @author Fletcher Nichol class TmpZip # Contructs a new Zip file for the given directory. # # There are 2 ways to interpret the directory path: # # * If the directory has no path separator terminator, then the # directory basename will be used as the base directory in the # resulting zip file. # * If the directory has a path separator terminator (such as `/` or # `\\`), then the entries under the directory will be added to the # resulting zip file. # # The following emaples assume a directory tree structure of: # # src # |-- alpha.txt # |-- beta.txt # \-- sub # \-- charlie.txt # # @example Including the base directory in the zip file # # TmpZip.new("/path/to/src") # # produces a zip file with entries: # # - src/alpha.txt # # - src/beta.txt # # - src/sub/charlie.txt # # @example Excluding the base directory in the zip file # # TmpZip.new("/path/to/src/") # # produces a zip file with entries: # # - alpha.txt # # - beta.txt # # - sub/charlie.txt # # @param dir [String,Pathname,#to_s] path to the directory # @param logger [#debug,#debug?] an optional logger/ui object that # responds to `#debug` and `#debug?` (default `nil`) def initialize(dir, logger = nil) @logger = logger || Logging.logger[self] @dir = clean_dirname(dir) @zip_io = Tempfile.open(['tmpzip-', '.zip'], binmode: true) write_zip @zip_io.close end # @return [Pathname] path to zip file def path Pathname.new(zip_io.path) if zip_io.path end # Unlinks (deletes) the zip file from the filesystem. def unlink zip_io.unlink end private # @return [Pathname] the directory used to create the Zip file # @api private attr_reader :dir # @return [#debug] the logger # @api private attr_reader :logger # @return [IO] the Zip file IO # @api private attr_reader :zip_io # @return [Pathname] the pathname object representing dirname that # doesn't have any of those ~ in it # @api private def clean_dirname(dir) paths = Pathname.glob(dir) if paths.length != 1 fail "Expected Pathname.glob(dir) to return only dir, got #{paths}" end paths.first end # @return [Array # @api private class NoDupIO < SimpleDelegator # @return [self] returns self and does *not* return a duplicate # object def dup self end end end end end end