winrm-fs 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +9 -5
- data/Rakefile +2 -4
- data/VERSION +1 -1
- data/appveyor.yml +39 -0
- data/changelog.md +9 -0
- data/lib/winrm-fs/core/file_transporter.rb +506 -0
- data/lib/winrm-fs/core/tmp_zip.rb +166 -0
- data/lib/winrm-fs/file_manager.rb +14 -15
- data/lib/winrm-fs/scripts/check_files.ps1.erb +48 -0
- data/lib/winrm-fs/scripts/decode_files.ps1.erb +59 -0
- data/lib/winrm-fs/scripts/download.ps1.erb +2 -1
- data/spec/config-example.yml +1 -1
- data/spec/{file_manager_spec.rb → integration/file_manager_spec.rb} +38 -12
- data/spec/integration/tmp_zip_spec.rb +26 -0
- data/spec/spec_helper.rb +28 -4
- data/spec/unit/file_transporter_spec.rb +819 -0
- data/spec/unit/tmp_zip_spec.rb +79 -0
- data/winrm-fs.gemspec +2 -1
- metadata +27 -12
- data/benchmark.rb +0 -20
- data/lib/winrm-fs/core/command_executor.rb +0 -74
- data/lib/winrm-fs/core/file_uploader.rb +0 -84
- data/lib/winrm-fs/core/temp_zip_file.rb +0 -187
- data/lib/winrm-fs/core/upload_orchestrator.rb +0 -119
- data/lib/winrm-fs/scripts/decode_file.ps1.erb +0 -36
- data/spec/temp_zip_file_spec.rb +0 -55
@@ -0,0 +1,79 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Author:: Fletcher (<fnichol@nichol.ca>)
|
4
|
+
#
|
5
|
+
# Copyright (C) 2015, Fletcher Nichol
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the 'License');
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an 'AS IS' BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
|
19
|
+
require 'winrm-fs/core/tmp_zip'
|
20
|
+
|
21
|
+
describe WinRM::FS::Core::TmpZip do
|
22
|
+
let(:src_dir) do
|
23
|
+
tmpdir = Pathname.new(Dir.mktmpdir)
|
24
|
+
@tmpdirs << tmpdir
|
25
|
+
src_dir = tmpdir.join('src')
|
26
|
+
sub_dir = src_dir.join('veggies')
|
27
|
+
|
28
|
+
src_dir.mkpath
|
29
|
+
create_local_file(src_dir.join('apple.txt'), 'appleapple')
|
30
|
+
create_local_file(src_dir.join('banana.txt'), 'bananabanana')
|
31
|
+
create_local_file(src_dir.join('cherry.txt'), 'cherrycherry')
|
32
|
+
sub_dir.mkpath
|
33
|
+
create_local_file(sub_dir.join('carrot.txt'), 'carrotcarrot')
|
34
|
+
src_dir
|
35
|
+
end
|
36
|
+
|
37
|
+
let(:tmp_zip) { WinRM::FS::Core::TmpZip.new(src_dir) }
|
38
|
+
|
39
|
+
before { @tmpdirs = [] }
|
40
|
+
|
41
|
+
after do
|
42
|
+
@tmpdirs.each(&:rmtree)
|
43
|
+
tmp_zip.unlink if tmp_zip.path
|
44
|
+
end
|
45
|
+
|
46
|
+
it '#path returns path to created zip file' do
|
47
|
+
expect(tmp_zip.path.file?).to eq true
|
48
|
+
end
|
49
|
+
|
50
|
+
it '#unlink removes the file' do
|
51
|
+
path = tmp_zip.path
|
52
|
+
expect(path.file?).to eq true
|
53
|
+
|
54
|
+
tmp_zip.unlink
|
55
|
+
|
56
|
+
expect(path.file?).to eq false
|
57
|
+
expect(tmp_zip.path).to eq nil
|
58
|
+
end
|
59
|
+
|
60
|
+
describe 'for a zip file containing the base directory' do
|
61
|
+
let(:tmp_zip) { WinRM::FS::Core::TmpZip.new(src_dir) }
|
62
|
+
|
63
|
+
it 'contains the input entries' do
|
64
|
+
zip = Zip::File.new(tmp_zip.path)
|
65
|
+
|
66
|
+
expect(zip.map(&:name).sort).to eq(
|
67
|
+
['apple.txt', 'banana.txt', 'cherry.txt', 'veggies/carrot.txt']
|
68
|
+
)
|
69
|
+
expect(zip.read('apple.txt')).to eq 'appleapple'
|
70
|
+
expect(zip.read('banana.txt')).to eq 'bananabanana'
|
71
|
+
expect(zip.read('cherry.txt')).to eq 'cherrycherry'
|
72
|
+
expect(zip.read('veggies/carrot.txt')).to eq 'carrotcarrot'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def create_local_file(path, content)
|
77
|
+
path.open('wb') { |file| file.write(content) }
|
78
|
+
end
|
79
|
+
end
|
data/winrm-fs.gemspec
CHANGED
@@ -29,7 +29,8 @@ Gem::Specification.new do |s|
|
|
29
29
|
s.add_runtime_dependency 'erubis', '~> 2.7'
|
30
30
|
s.add_runtime_dependency 'logging', '~> 1.6', '>= 1.6.1'
|
31
31
|
s.add_runtime_dependency 'rubyzip', '~> 1.1'
|
32
|
-
s.add_runtime_dependency 'winrm', '~> 1.
|
32
|
+
s.add_runtime_dependency 'winrm', '~> 1.5'
|
33
|
+
s.add_development_dependency 'pry'
|
33
34
|
s.add_development_dependency 'rspec', '~> 3.0.0'
|
34
35
|
s.add_development_dependency 'rake', '~> 10.3.2'
|
35
36
|
s.add_development_dependency 'rubocop', '~> 0.28.0'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: winrm-fs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shawn Neal
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2016-01-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: erubis
|
@@ -65,14 +65,28 @@ dependencies:
|
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 1.
|
68
|
+
version: '1.5'
|
69
69
|
type: :runtime
|
70
70
|
prerelease: false
|
71
71
|
version_requirements: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 1.
|
75
|
+
version: '1.5'
|
76
|
+
- !ruby/object:Gem::Dependency
|
77
|
+
name: pry
|
78
|
+
requirement: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
type: :development
|
84
|
+
prerelease: false
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
76
90
|
- !ruby/object:Gem::Dependency
|
77
91
|
name: rspec
|
78
92
|
requirement: !ruby/object:Gem::Requirement
|
@@ -137,28 +151,29 @@ files:
|
|
137
151
|
- Rakefile
|
138
152
|
- VERSION
|
139
153
|
- Vagrantfile
|
140
|
-
-
|
154
|
+
- appveyor.yml
|
141
155
|
- bin/rwinrmcp
|
142
156
|
- changelog.md
|
143
157
|
- lib/winrm-fs.rb
|
144
|
-
- lib/winrm-fs/core/
|
145
|
-
- lib/winrm-fs/core/
|
146
|
-
- lib/winrm-fs/core/temp_zip_file.rb
|
147
|
-
- lib/winrm-fs/core/upload_orchestrator.rb
|
158
|
+
- lib/winrm-fs/core/file_transporter.rb
|
159
|
+
- lib/winrm-fs/core/tmp_zip.rb
|
148
160
|
- lib/winrm-fs/exceptions.rb
|
149
161
|
- lib/winrm-fs/file_manager.rb
|
162
|
+
- lib/winrm-fs/scripts/check_files.ps1.erb
|
150
163
|
- lib/winrm-fs/scripts/checksum.ps1.erb
|
151
164
|
- lib/winrm-fs/scripts/create_dir.ps1.erb
|
152
|
-
- lib/winrm-fs/scripts/
|
165
|
+
- lib/winrm-fs/scripts/decode_files.ps1.erb
|
153
166
|
- lib/winrm-fs/scripts/delete.ps1.erb
|
154
167
|
- lib/winrm-fs/scripts/download.ps1.erb
|
155
168
|
- lib/winrm-fs/scripts/exists.ps1.erb
|
156
169
|
- lib/winrm-fs/scripts/scripts.rb
|
157
170
|
- spec/config-example.yml
|
158
|
-
- spec/file_manager_spec.rb
|
171
|
+
- spec/integration/file_manager_spec.rb
|
172
|
+
- spec/integration/tmp_zip_spec.rb
|
159
173
|
- spec/matchers.rb
|
160
174
|
- spec/spec_helper.rb
|
161
|
-
- spec/
|
175
|
+
- spec/unit/file_transporter_spec.rb
|
176
|
+
- spec/unit/tmp_zip_spec.rb
|
162
177
|
- winrm-fs.gemspec
|
163
178
|
homepage: http://github.com/WinRb/winrm-fs
|
164
179
|
licenses: []
|
data/benchmark.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
require 'winrm-fs'
|
3
|
-
require 'benchmark'
|
4
|
-
|
5
|
-
def files
|
6
|
-
# This is a fairly short list of small files, may also want a benchmark with larger files
|
7
|
-
`git ls-files`.lines.map(&:strip)
|
8
|
-
end
|
9
|
-
|
10
|
-
def create_zip(factory, file)
|
11
|
-
WinRM::FS::Core::TempZipFile.new(Dir.pwd, zip_file: file, via: factory, X: true) do | temp_zip |
|
12
|
-
temp_zip.add(*files)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
Benchmark.bm do | benchmark |
|
17
|
-
benchmark.report('zip cmd') { `git ls-files | zip zip_command.zip -X --names-stdin` }
|
18
|
-
benchmark.report('shell') { create_zip(:shell, 'shell.zip') }
|
19
|
-
benchmark.report('ruby') { create_zip(:rubyzip, 'ruby.zip') }
|
20
|
-
end
|
@@ -1,74 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
#
|
3
|
-
# Copyright 2015 Shawn Neal <sneal@sneal.net>
|
4
|
-
#
|
5
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
-
# you may not use this file except in compliance with the License.
|
7
|
-
# You may obtain a copy of the License at
|
8
|
-
#
|
9
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
11
|
-
# Unless required by applicable law or agreed to in writing, software
|
12
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
-
# See the License for the specific language governing permissions and
|
15
|
-
# limitations under the License.
|
16
|
-
|
17
|
-
module WinRM
|
18
|
-
module FS
|
19
|
-
module Core
|
20
|
-
# Executes commands used by the WinRM file management module
|
21
|
-
class CommandExecutor
|
22
|
-
def initialize(service)
|
23
|
-
@service = service
|
24
|
-
end
|
25
|
-
|
26
|
-
def open
|
27
|
-
@shell = @service.open_shell
|
28
|
-
@shell_open = true
|
29
|
-
end
|
30
|
-
|
31
|
-
def close
|
32
|
-
@service.close_shell(@shell) if @shell
|
33
|
-
@shell_open = false
|
34
|
-
end
|
35
|
-
|
36
|
-
def run_powershell(script)
|
37
|
-
assert_shell_is_open
|
38
|
-
run_cmd('powershell', ['-encodedCommand', encode_script(safe_script(script))])
|
39
|
-
end
|
40
|
-
|
41
|
-
def run_cmd(command, arguments = [])
|
42
|
-
assert_shell_is_open
|
43
|
-
result = nil
|
44
|
-
@service.run_command(@shell, command, arguments) do |command_id|
|
45
|
-
result = @service.get_command_output(@shell, command_id)
|
46
|
-
end
|
47
|
-
assert_command_success(command, result)
|
48
|
-
result.stdout
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
def assert_shell_is_open
|
54
|
-
fail 'You must call open before calling any run methods' unless @shell_open
|
55
|
-
end
|
56
|
-
|
57
|
-
def assert_command_success(command, result)
|
58
|
-
return if result[:exitcode] == 0 && result.stderr.length == 0
|
59
|
-
fail WinRMUploadError, command + '\n' + result.output
|
60
|
-
end
|
61
|
-
|
62
|
-
def encode_script(script)
|
63
|
-
encoded_script = script.encode('UTF-16LE', 'UTF-8')
|
64
|
-
Base64.strict_encode64(encoded_script)
|
65
|
-
end
|
66
|
-
|
67
|
-
# suppress the progress stream from leaking to stderr
|
68
|
-
def safe_script(script)
|
69
|
-
"$ProgressPreference='SilentlyContinue';" + script
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
@@ -1,84 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
#
|
3
|
-
# Copyright 2015 Shawn Neal <sneal@sneal.net>
|
4
|
-
#
|
5
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
-
# you may not use this file except in compliance with the License.
|
7
|
-
# You may obtain a copy of the License at
|
8
|
-
#
|
9
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
11
|
-
# Unless required by applicable law or agreed to in writing, software
|
12
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
-
# See the License for the specific language governing permissions and
|
15
|
-
# limitations under the License.
|
16
|
-
|
17
|
-
require_relative 'command_executor'
|
18
|
-
|
19
|
-
module WinRM
|
20
|
-
module FS
|
21
|
-
module Core
|
22
|
-
# Uploads the given source file to a temp file in 8k chunks
|
23
|
-
class FileUploader
|
24
|
-
def initialize(command_executor)
|
25
|
-
@command_executor = command_executor
|
26
|
-
end
|
27
|
-
|
28
|
-
# Uploads the given file to the specified temp file as base64 encoded.
|
29
|
-
#
|
30
|
-
# @param [String] Path to the local source file on this machine
|
31
|
-
# @param [String] Path to the file on the target machine
|
32
|
-
# @return [Integer] Count of bytes uploaded
|
33
|
-
def upload(local_file, remote_file, &block)
|
34
|
-
@command_executor.run_powershell(prepare_script(remote_file))
|
35
|
-
do_upload(local_file, dos_path(remote_file), &block)
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def do_upload(local_file, remote_file)
|
41
|
-
bytes_copied = 0
|
42
|
-
base64_array = base64_content(local_file)
|
43
|
-
base64_array.each_slice(8000 - remote_file.size) do |chunk|
|
44
|
-
@command_executor.run_cmd("echo #{chunk.join} >> \"#{remote_file}\"")
|
45
|
-
bytes_copied += chunk.count
|
46
|
-
yield bytes_copied, base64_array.count if block_given?
|
47
|
-
end
|
48
|
-
base64_array.length
|
49
|
-
end
|
50
|
-
|
51
|
-
def base64_content(local_file)
|
52
|
-
base64_host_file = Base64.encode64(IO.binread(local_file)).gsub("\n", '')
|
53
|
-
base64_host_file.chars.to_a
|
54
|
-
end
|
55
|
-
|
56
|
-
def dos_path(path)
|
57
|
-
# TODO: convert all env vars
|
58
|
-
path = path.gsub(/\$env:TEMP/, '%TEMP%')
|
59
|
-
path.gsub(/\\/, '/')
|
60
|
-
end
|
61
|
-
|
62
|
-
# rubocop:disable Metrics/MethodLength
|
63
|
-
def prepare_script(remote_file)
|
64
|
-
<<-EOH
|
65
|
-
$p = $ExecutionContext.SessionState.Path
|
66
|
-
$path = $p.GetUnresolvedProviderPathFromPSPath("#{remote_file}")
|
67
|
-
|
68
|
-
# if the file exists, truncate it
|
69
|
-
if (Test-Path $path -PathType Leaf) {
|
70
|
-
'' | Set-Content $path
|
71
|
-
}
|
72
|
-
|
73
|
-
# ensure the target directory exists
|
74
|
-
$dir = [System.IO.Path]::GetDirectoryName($path)
|
75
|
-
if (!(Test-Path $dir -PathType Container)) {
|
76
|
-
mkdir $dir -ErrorAction SilentlyContinue | Out-Null
|
77
|
-
}
|
78
|
-
EOH
|
79
|
-
end
|
80
|
-
# rubocop:enable Metrics/MethodLength
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
@@ -1,187 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
#
|
3
|
-
# Copyright 2015 Shawn Neal <sneal@sneal.net>
|
4
|
-
#
|
5
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
-
# you may not use this file except in compliance with the License.
|
7
|
-
# You may obtain a copy of the License at
|
8
|
-
#
|
9
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
11
|
-
# Unless required by applicable law or agreed to in writing, software
|
12
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
-
# See the License for the specific language governing permissions and
|
15
|
-
# limitations under the License.
|
16
|
-
|
17
|
-
require 'English'
|
18
|
-
require 'zip'
|
19
|
-
require 'fileutils'
|
20
|
-
require 'pathname'
|
21
|
-
|
22
|
-
module WinRM
|
23
|
-
module FS
|
24
|
-
module Core
|
25
|
-
# Temporary zip file on the local system
|
26
|
-
class TempZipFile
|
27
|
-
attr_reader :zip_file, :path, :paths, :basedir, :options
|
28
|
-
|
29
|
-
# Creates a new local temporary zip file
|
30
|
-
# @param [String] Base directory to use when expanding out files passed to add
|
31
|
-
# @param [Hash] Options: zip_file, via, recurse_paths
|
32
|
-
def initialize(basedir = Dir.pwd, options = {})
|
33
|
-
@basedir = Pathname.new(basedir)
|
34
|
-
@options = options
|
35
|
-
@zip_file = options[:zip_file] || Tempfile.new(['winrm_upload', '.zip'])
|
36
|
-
@zip_file.close unless @zip_file.respond_to?('closed?') && @zip_file.closed?
|
37
|
-
@path = Pathname.new(@zip_file)
|
38
|
-
end
|
39
|
-
|
40
|
-
# Adds a file or directory to the temporary zip file
|
41
|
-
# @param [String] Directory or file path relative to basedir to add into zip
|
42
|
-
def add(*new_paths)
|
43
|
-
new_paths.each do | path |
|
44
|
-
absolute_path = File.expand_path(path, basedir)
|
45
|
-
fail "#{path} must exist relative to #{basedir}" unless File.exist? absolute_path
|
46
|
-
paths << Pathname.new(absolute_path).relative_path_from(basedir)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def paths
|
51
|
-
@paths ||= []
|
52
|
-
end
|
53
|
-
|
54
|
-
def delete
|
55
|
-
@zip_file.delete
|
56
|
-
end
|
57
|
-
|
58
|
-
def build
|
59
|
-
factory.new(self).build
|
60
|
-
end
|
61
|
-
|
62
|
-
private
|
63
|
-
|
64
|
-
def factory
|
65
|
-
@factory ||= case options[:via]
|
66
|
-
when nil, :rubyzip
|
67
|
-
RubyZipFactory
|
68
|
-
when :shell
|
69
|
-
ShellZipFactory
|
70
|
-
else
|
71
|
-
fail "Unknown zip factory: #{factory}"
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
# Creates a zip file by shelling out to the zip command
|
77
|
-
class ShellZipFactory
|
78
|
-
attr_reader :zip_definition, :basedir, :zip_file, :paths, :options
|
79
|
-
|
80
|
-
def initialize(zip_definition)
|
81
|
-
@zip_definition = zip_definition
|
82
|
-
@zip_file = zip_definition.zip_file
|
83
|
-
@basedir = zip_definition.basedir
|
84
|
-
@paths = zip_definition.paths
|
85
|
-
@options = build_options.push('--names-stdin').join(' ')
|
86
|
-
end
|
87
|
-
|
88
|
-
def build
|
89
|
-
Dir.chdir(basedir) do
|
90
|
-
# zip doesn't like the file that already exists
|
91
|
-
output = `zip #{zip_definition.path}.tmp #{options} < #{write_file_list.path}`
|
92
|
-
fail "zip command failed: #{output}" unless $CHILD_STATUS.success?
|
93
|
-
|
94
|
-
FileUtils.mv("#{zip_definition.path}.tmp", "#{zip_definition.path}")
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
private
|
99
|
-
|
100
|
-
def write_file_list
|
101
|
-
file_list = Tempfile.new('file_list')
|
102
|
-
file_list.puts paths.join("\n")
|
103
|
-
file_list.close
|
104
|
-
file_list
|
105
|
-
end
|
106
|
-
|
107
|
-
def build_options
|
108
|
-
zip_definition.options.map do | key, value |
|
109
|
-
prefix = key.length > 1 ? '--' : '-'
|
110
|
-
if value == true
|
111
|
-
"#{prefix}#{key}"
|
112
|
-
else
|
113
|
-
"#{prefix}#{key} #{value}"
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
# Creates a zip file using RubyZip
|
120
|
-
class RubyZipFactory
|
121
|
-
attr_reader :zip_definition, :basedir
|
122
|
-
|
123
|
-
def initialize(zip_definition)
|
124
|
-
@zip_definition = zip_definition
|
125
|
-
@basedir = zip_definition.basedir
|
126
|
-
@zip = Zip::File.open(zip_definition.path, Zip::File::CREATE)
|
127
|
-
end
|
128
|
-
|
129
|
-
def build
|
130
|
-
@zip_definition.paths.each do | path |
|
131
|
-
absolute_path = File.expand_path(path, basedir)
|
132
|
-
fail "#{path} doesn't exist" unless File.exist? absolute_path
|
133
|
-
|
134
|
-
if File.directory?(absolute_path)
|
135
|
-
add_directory(path)
|
136
|
-
else
|
137
|
-
add_file(path)
|
138
|
-
end
|
139
|
-
end
|
140
|
-
close
|
141
|
-
end
|
142
|
-
|
143
|
-
def close
|
144
|
-
@zip.close if @zip
|
145
|
-
end
|
146
|
-
|
147
|
-
private
|
148
|
-
|
149
|
-
# Adds all files in the specified directory recursively into the zip file
|
150
|
-
# @param [String] Directory to add into zip
|
151
|
-
def add_directory(dir)
|
152
|
-
glob_pattern = '*'
|
153
|
-
glob_pattern = '**/*' if zip_definition.options[:recurse_paths]
|
154
|
-
|
155
|
-
glob = File.join(basedir, dir, glob_pattern)
|
156
|
-
Dir.glob(glob).each do |file|
|
157
|
-
add_file(file)
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
def add_file(file)
|
162
|
-
write_zip_entry(file, basedir)
|
163
|
-
end
|
164
|
-
|
165
|
-
def write_zip_entry(file, _file_entry_path)
|
166
|
-
absolute_file = File.expand_path(file, basedir)
|
167
|
-
relative_file = Pathname.new(absolute_file).relative_path_from(basedir).to_s
|
168
|
-
entry = new_zip_entry(relative_file)
|
169
|
-
@zip.add(entry, absolute_file)
|
170
|
-
end
|
171
|
-
|
172
|
-
def new_zip_entry(file_entry_path)
|
173
|
-
Zip::Entry.new(
|
174
|
-
@zip,
|
175
|
-
file_entry_path,
|
176
|
-
nil,
|
177
|
-
nil,
|
178
|
-
nil,
|
179
|
-
nil,
|
180
|
-
nil,
|
181
|
-
nil,
|
182
|
-
::Zip::DOSTime.new(2000))
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
186
|
-
end
|
187
|
-
end
|