winrm-fs 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|