winrm-transport 1.0.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 +7 -0
- data/.cane +2 -0
- data/.gitignore +15 -0
- data/.travis.yml +26 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +13 -0
- data/Guardfile +27 -0
- data/LICENSE.txt +15 -0
- data/README.md +80 -0
- data/Rakefile +49 -0
- data/bin/console +7 -0
- data/bin/setup +7 -0
- data/lib/winrm/transport.rb +28 -0
- data/lib/winrm/transport/command_executor.rb +217 -0
- data/lib/winrm/transport/file_transporter.rb +468 -0
- data/lib/winrm/transport/logging.rb +47 -0
- data/lib/winrm/transport/shell_closer.rb +71 -0
- data/lib/winrm/transport/tmp_zip.rb +184 -0
- data/lib/winrm/transport/version.rb +25 -0
- data/support/check_files.ps1 +46 -0
- data/support/decode_files.ps1 +60 -0
- data/winrm-transport.gemspec +52 -0
- metadata +272 -0
@@ -0,0 +1,47 @@
|
|
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
|
+
module WinRM
|
20
|
+
|
21
|
+
module Transport
|
22
|
+
|
23
|
+
# Mixin to use an optionally provided logger for logging.
|
24
|
+
#
|
25
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
26
|
+
module Logging
|
27
|
+
|
28
|
+
# Logs a message on the logger at the debug level, if a logger is
|
29
|
+
# present.
|
30
|
+
#
|
31
|
+
# @param msg [String] a message to log
|
32
|
+
# @yield evaluates and uses return value as message to log. If msg
|
33
|
+
# parameter is set, it will take precedence over the block.
|
34
|
+
def debug(msg = nil, &block)
|
35
|
+
return if logger.nil? || !logger.debug?
|
36
|
+
logger.debug("[#{log_subject}] " << (msg || block.call))
|
37
|
+
end
|
38
|
+
|
39
|
+
# The subject for log messages.
|
40
|
+
#
|
41
|
+
# @return [String] log subject
|
42
|
+
def log_subject
|
43
|
+
@log_subject ||= self.class.to_s.split("::").last
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Author:: Fletcher Nichol (<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
|
+
module WinRM
|
20
|
+
|
21
|
+
module Transport
|
22
|
+
|
23
|
+
# An object that can close a remote shell session over WinRM.
|
24
|
+
#
|
25
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
26
|
+
class ShellCloser
|
27
|
+
|
28
|
+
# @return [String,nil] the identifier for the current open remote
|
29
|
+
# shell session
|
30
|
+
attr_accessor :shell_id
|
31
|
+
|
32
|
+
# Constructs a new ShellCloser.
|
33
|
+
#
|
34
|
+
# @param info [String] a string representation of the connection
|
35
|
+
# @param debug [true,false] whether or not debug messages should be
|
36
|
+
# output
|
37
|
+
# @param args [Array] arguments to construct a `WinRM::WinRMWebService`
|
38
|
+
def initialize(info, debug, args)
|
39
|
+
@info = info
|
40
|
+
@debug = debug
|
41
|
+
@args = args
|
42
|
+
end
|
43
|
+
|
44
|
+
# Closes the remote shell session.
|
45
|
+
def call(*)
|
46
|
+
debug("[CommandExecutor] closing remote shell #{@shell_id} on #{@info}")
|
47
|
+
::WinRM::WinRMWebService.new(*@args).close_shell(@shell_id)
|
48
|
+
debug("[CommandExecutor] remote shell #{@shell_id} closed")
|
49
|
+
rescue => e
|
50
|
+
debug("Exception: #{e.inspect}")
|
51
|
+
end
|
52
|
+
|
53
|
+
# @param shell_id [String] a remote shell ID
|
54
|
+
# @return [ShellCloser] a new ShellCloser with a copy of this object's
|
55
|
+
# state and the shell_id set to the given parameter value
|
56
|
+
def for(shell_id)
|
57
|
+
self.class.new(@info, @debug, @args).tap { |c| c.shell_id = shell_id }
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# Writes a debug message, if debug mode is enabled.
|
63
|
+
#
|
64
|
+
# @param message [String] a message
|
65
|
+
# @api private
|
66
|
+
def debug(message)
|
67
|
+
$stdout.puts "D #{message}" if @debug
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,184 @@
|
|
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 "delegate"
|
20
|
+
require "pathname"
|
21
|
+
require "tempfile"
|
22
|
+
require "zip"
|
23
|
+
|
24
|
+
require "winrm/transport/logging"
|
25
|
+
|
26
|
+
module WinRM
|
27
|
+
|
28
|
+
module Transport
|
29
|
+
|
30
|
+
# A temporary Zip file for a given directory.
|
31
|
+
#
|
32
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
33
|
+
class TmpZip
|
34
|
+
|
35
|
+
include Logging
|
36
|
+
|
37
|
+
# Contructs a new Zip file for the given directory.
|
38
|
+
#
|
39
|
+
# There are 2 ways to interpret the directory path:
|
40
|
+
#
|
41
|
+
# * If the directory has no path separator terminator, then the
|
42
|
+
# directory basename will be used as the base directory in the
|
43
|
+
# resulting zip file.
|
44
|
+
# * If the directory has a path separator terminator (such as `/` or
|
45
|
+
# `\\`), then the entries under the directory will be added to the
|
46
|
+
# resulting zip file.
|
47
|
+
#
|
48
|
+
# The following emaples assume a directory tree structure of:
|
49
|
+
#
|
50
|
+
# src
|
51
|
+
# |-- alpha.txt
|
52
|
+
# |-- beta.txt
|
53
|
+
# \-- sub
|
54
|
+
# \-- charlie.txt
|
55
|
+
#
|
56
|
+
# @example Including the base directory in the zip file
|
57
|
+
#
|
58
|
+
# TmpZip.new("/path/to/src")
|
59
|
+
# # produces a zip file with entries:
|
60
|
+
# # - src/alpha.txt
|
61
|
+
# # - src/beta.txt
|
62
|
+
# # - src/sub/charlie.txt
|
63
|
+
#
|
64
|
+
# @example Excluding the base directory in the zip file
|
65
|
+
#
|
66
|
+
# TmpZip.new("/path/to/src/")
|
67
|
+
# # produces a zip file with entries:
|
68
|
+
# # - alpha.txt
|
69
|
+
# # - beta.txt
|
70
|
+
# # - sub/charlie.txt
|
71
|
+
#
|
72
|
+
# @param dir [String,Pathname,#to_s] path to the directory
|
73
|
+
# @param logger [#debug,#debug?] an optional logger/ui object that
|
74
|
+
# responds to `#debug` and `#debug?` (default `nil`)
|
75
|
+
def initialize(dir, logger = nil)
|
76
|
+
@logger = logger
|
77
|
+
@dir = Pathname.new(dir)
|
78
|
+
@method = ::Zip::Entry::DEFLATED
|
79
|
+
@compression = Zlib::BEST_COMPRESSION
|
80
|
+
@zip_io = Tempfile.open(["tmpzip-", ".zip"], :binmode => true)
|
81
|
+
write_zip
|
82
|
+
@zip_io.close
|
83
|
+
end
|
84
|
+
|
85
|
+
# @return [Pathname] path to zip file
|
86
|
+
def path
|
87
|
+
Pathname.new(zip_io.path) if zip_io.path
|
88
|
+
end
|
89
|
+
|
90
|
+
# Unlinks (deletes) the zip file from the filesystem.
|
91
|
+
def unlink
|
92
|
+
zip_io.unlink
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
# @return [Integer] the compression used for Zip entries. Possible
|
98
|
+
# values are `Zlib::BEST_COMPRESSION`, `Zlib::DEFAULT_COMPRESSION`,
|
99
|
+
# and `Zlib::NO_COMPRESSION`.
|
100
|
+
# @api private
|
101
|
+
attr_reader :compression
|
102
|
+
|
103
|
+
# @return [Pathname] the directory used to create the Zip file
|
104
|
+
# @api private
|
105
|
+
attr_reader :dir
|
106
|
+
|
107
|
+
# @return [#debug] the logger
|
108
|
+
# @api private
|
109
|
+
attr_reader :logger
|
110
|
+
|
111
|
+
# @return [Integer] compression method used for Zip entries. Possible
|
112
|
+
# values are `Zip::Entry::DEFLATED` and `Zip::Entry::STORED`.
|
113
|
+
# @api private
|
114
|
+
attr_reader :method
|
115
|
+
|
116
|
+
# @return [IO] the Zip file IO
|
117
|
+
# @api private
|
118
|
+
attr_reader :zip_io
|
119
|
+
|
120
|
+
# @return [Pathname] the path segement to be stripped off Zip entries
|
121
|
+
# @api private
|
122
|
+
def dir_strip
|
123
|
+
@dir_strip ||= if dir.to_s.end_with?("/", "\\")
|
124
|
+
Pathname.new(dir.to_s.chop)
|
125
|
+
else
|
126
|
+
dir.dirname
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# @return [Array<Pathname] all recursive files under the base
|
131
|
+
# directory, excluding directories
|
132
|
+
# @api private
|
133
|
+
def entries
|
134
|
+
Pathname.glob(dir.join("**/*")).delete_if(&:directory?).sort
|
135
|
+
end
|
136
|
+
|
137
|
+
# (see Logging.log_subject)
|
138
|
+
# @api private
|
139
|
+
def log_subject
|
140
|
+
@log_subject ||= [self.class.to_s.split("::").last, path].join("::")
|
141
|
+
end
|
142
|
+
|
143
|
+
# Adds all file entries to the Zip output stream.
|
144
|
+
#
|
145
|
+
# @param zos [Zip::OutputStream] zip output stream
|
146
|
+
# @api private
|
147
|
+
def produce_zip_entries(zos)
|
148
|
+
entries.each do |entry|
|
149
|
+
entry_path = entry.sub("#{dir_strip}/", "")
|
150
|
+
debug { "+++ Adding #{entry_path}" }
|
151
|
+
zos.put_next_entry(entry_path, nil, nil, method, compression)
|
152
|
+
entry.open("rb") { |src| IO.copy_stream(src, zos) }
|
153
|
+
end
|
154
|
+
debug { "=== All files added." }
|
155
|
+
end
|
156
|
+
|
157
|
+
# Writes out a temporary Zip file.
|
158
|
+
#
|
159
|
+
# @api private
|
160
|
+
def write_zip
|
161
|
+
debug { "Populating files" }
|
162
|
+
Zip::OutputStream.write_buffer(NoDupIO.new(zip_io)) do |zos|
|
163
|
+
produce_zip_entries(zos)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# Simple delegate wrapper to prevent `#dup` calls being made on IO
|
168
|
+
# objects. This is used to bypass an issue in the `Zip::Outputstream`
|
169
|
+
# constructor where an incoming IO is duplicated, leading to races
|
170
|
+
# on flushing the final stream to disk.
|
171
|
+
#
|
172
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
173
|
+
# @api private
|
174
|
+
class NoDupIO < SimpleDelegator
|
175
|
+
|
176
|
+
# @return [self] returns self and does *not* return a duplicate
|
177
|
+
# object
|
178
|
+
def dup
|
179
|
+
self
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Author:: Fletcher Nichol (<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
|
+
module WinRM
|
20
|
+
|
21
|
+
module Transport
|
22
|
+
|
23
|
+
VERSION = "1.0.0"
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
Function Cleanup($o) { if (($o -ne $null) -and ($o.GetType().GetMethod("Dispose") -ne $null)) { $o.Dispose() } }
|
2
|
+
|
3
|
+
Function Decode-Base64File($src, $dst) {
|
4
|
+
Try {
|
5
|
+
$in = (Get-Item $src).OpenRead()
|
6
|
+
$b64 = New-Object -TypeName System.Security.Cryptography.FromBase64Transform
|
7
|
+
$m = [System.Security.Cryptography.CryptoStreamMode]::Read
|
8
|
+
$d = New-Object -TypeName System.Security.Cryptography.CryptoStream $in,$b64,$m
|
9
|
+
Copy-Stream $d ($out = [System.IO.File]::OpenWrite($dst))
|
10
|
+
} Finally { Cleanup $in; Cleanup $out; Cleanup $d }
|
11
|
+
}
|
12
|
+
|
13
|
+
Function Copy-Stream($src, $dst) { $b = New-Object Byte[] 4096; while (($i = $src.Read($b, 0, $b.Length)) -ne 0) { $dst.Write($b, 0, $i) } }
|
14
|
+
|
15
|
+
Function Check-Files($h) {
|
16
|
+
return $h.GetEnumerator() | ForEach-Object {
|
17
|
+
$dst = Unresolve-Path $_.Key
|
18
|
+
New-Object psobject -Property @{
|
19
|
+
chk_exists = ($exists = Test-Path $dst -PathType Leaf)
|
20
|
+
src_md5 = ($sMd5 = $_.Value)
|
21
|
+
dst_md5 = ($dMd5 = if ($exists) { Get-MD5Sum $dst } else { $null })
|
22
|
+
chk_dirty = ($dirty = if ($sMd5 -ne $dMd5) { $true } else { $false })
|
23
|
+
verifies = if ($dirty -eq $false) { $true } else { $false }
|
24
|
+
}
|
25
|
+
} | Select-Object -Property chk_exists,src_md5,dst_md5,chk_dirty,verifies
|
26
|
+
}
|
27
|
+
|
28
|
+
Function Get-MD5Sum($src) {
|
29
|
+
Try {
|
30
|
+
$c = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
|
31
|
+
$bytes = $c.ComputeHash(($in = (Get-Item $src).OpenRead()))
|
32
|
+
return ([System.BitConverter]::ToString($bytes)).Replace("-", "").ToLower()
|
33
|
+
} Finally { Cleanup $c; Cleanup $in }
|
34
|
+
}
|
35
|
+
|
36
|
+
Function Invoke-Input($in) {
|
37
|
+
$in = Unresolve-Path $in
|
38
|
+
Decode-Base64File $in ($decoded = "$($in).ps1")
|
39
|
+
$expr = Get-Content $decoded | Out-String
|
40
|
+
Remove-Item $in,$decoded -Force
|
41
|
+
return Invoke-Expression "$expr"
|
42
|
+
}
|
43
|
+
|
44
|
+
Function Unresolve-Path($p) { if ($p -eq $null) { return $null } else { return $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($p) } }
|
45
|
+
|
46
|
+
Check-Files (Invoke-Input $hash_file) | ConvertTo-Csv -NoTypeInformation
|
@@ -0,0 +1,60 @@
|
|
1
|
+
Function Cleanup($o) { if (($o -ne $null) -and ($o.GetType().GetMethod("Dispose") -ne $null)) { $o.Dispose() } }
|
2
|
+
|
3
|
+
Function Decode-Base64File($src, $dst) {
|
4
|
+
Try {
|
5
|
+
$in = (Get-Item $src).OpenRead()
|
6
|
+
$b64 = New-Object -TypeName System.Security.Cryptography.FromBase64Transform
|
7
|
+
$m = [System.Security.Cryptography.CryptoStreamMode]::Read
|
8
|
+
$d = New-Object -TypeName System.Security.Cryptography.CryptoStream $in,$b64,$m
|
9
|
+
echo $null > $dst
|
10
|
+
Copy-Stream $d ($out = [System.IO.File]::OpenWrite($dst))
|
11
|
+
} Finally { Cleanup $in; Cleanup $out; Cleanup $d }
|
12
|
+
}
|
13
|
+
|
14
|
+
Function Copy-Stream($src, $dst) { $b = New-Object Byte[] 4096; while (($i = $src.Read($b, 0, $b.Length)) -ne 0) { $dst.Write($b, 0, $i) } }
|
15
|
+
|
16
|
+
Function Decode-Files($hash) {
|
17
|
+
$hash.GetEnumerator() | ForEach-Object {
|
18
|
+
$tmp = Unresolve-Path $_.Key
|
19
|
+
$sMd5 = (Get-Item $tmp).BaseName.Replace("b64-", "")
|
20
|
+
$tzip, $dst = (Unresolve-Path $_.Value["tmpzip"]), (Unresolve-Path $_.Value["dst"])
|
21
|
+
$decoded = if ($tzip -ne $null) { $tzip } else { $dst }
|
22
|
+
Decode-Base64File $tmp $decoded
|
23
|
+
Remove-Item $tmp -Force
|
24
|
+
$dMd5 = Get-MD5Sum $decoded
|
25
|
+
$verifies = if ($sMd5 -eq $dMd5) { $true } else { $false }
|
26
|
+
if ($tzip) { Unzip-File $tzip $dst; Remove-Item $tzip -Force }
|
27
|
+
New-Object psobject -Property @{ dst = $dst; verifies = $verifies; src_md5 = $sMd5; dst_md5 = $dMd5; tmpfile = $tmp; tmpzip = $tzip }
|
28
|
+
} | Select-Object -Property dst,verifies,src_md5,dst_md5,tmpfile,tmpzip
|
29
|
+
}
|
30
|
+
|
31
|
+
Function Get-MD5Sum($src) {
|
32
|
+
Try {
|
33
|
+
$c = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
|
34
|
+
$bytes = $c.ComputeHash(($in = (Get-Item $src).OpenRead()))
|
35
|
+
return ([System.BitConverter]::ToString($bytes)).Replace("-", "").ToLower()
|
36
|
+
} Finally { Cleanup $c; Cleanup $in }
|
37
|
+
}
|
38
|
+
|
39
|
+
Function Invoke-Input($in) {
|
40
|
+
$in = Unresolve-Path $in
|
41
|
+
Decode-Base64File $in ($decoded = "$($in).ps1")
|
42
|
+
$expr = Get-Content $decoded | Out-String
|
43
|
+
Remove-Item $in,$decoded -Force
|
44
|
+
return Invoke-Expression "$expr"
|
45
|
+
}
|
46
|
+
|
47
|
+
Function Release-COM($o) { if ($o -ne $null) { [void][System.Runtime.Interopservices.Marshal]::ReleaseComObject($o) } }
|
48
|
+
|
49
|
+
Function Unresolve-Path($p) { if ($p -eq $null) { return $null } else { return $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($p) } }
|
50
|
+
|
51
|
+
Function Unzip-File($src, $dst) {
|
52
|
+
$r = "HKLM:\Software\Microsoft\NET Framework Setup\NDP\v4"
|
53
|
+
if (($PSVersionTable.PSVersion.Major -ge 3) -and ((gp "$r\Full").Version -like "4.5*" -or (gp "$r\Client").Version -like "4.5*")) {
|
54
|
+
[System.Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem") | Out-Null; [System.IO.Compression.ZipFile]::ExtractToDirectory("$src", "$dst")
|
55
|
+
} else {
|
56
|
+
Try { $s = New-Object -ComObject Shell.Application; ($dp = $s.NameSpace($dst)).CopyHere(($z = $s.NameSpace($src)).Items(), 0x610) } Finally { Release-Com $s; Release-Com $z; Release-COM $dp }
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
Decode-Files (Invoke-Input $hash_file) | ConvertTo-Csv -NoTypeInformation
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "winrm/transport/version"
|
5
|
+
require "English"
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "winrm-transport"
|
9
|
+
spec.version = WinRM::Transport::VERSION
|
10
|
+
spec.authors = ["Fletcher Nichol"]
|
11
|
+
spec.email = ["fnichol@nichol.ca"]
|
12
|
+
|
13
|
+
spec.summary = "WinRM transport logic for re-using remote shells " \
|
14
|
+
"and uploading files. The original code was extracted " \
|
15
|
+
"from the Test Kitchen project and remains the " \
|
16
|
+
"primary reference use case."
|
17
|
+
|
18
|
+
spec.description = spec.summary
|
19
|
+
spec.homepage = "https://github.com/test-kitchen/winrm-transport"
|
20
|
+
spec.license = "Apache 2.0"
|
21
|
+
|
22
|
+
spec.files = `git ls-files -z`.split("\x0").
|
23
|
+
reject { |f| f.match(%r{^(test|spec|features)/}) }
|
24
|
+
|
25
|
+
spec.bindir = "exe"
|
26
|
+
spec.executables = []
|
27
|
+
spec.require_paths = ["lib"]
|
28
|
+
|
29
|
+
spec.required_ruby_version = ">= 1.9.1"
|
30
|
+
|
31
|
+
spec.add_dependency "winrm", "~> 1.3"
|
32
|
+
spec.add_dependency "rubyzip", ">= 1.1.7", "~> 1.1"
|
33
|
+
|
34
|
+
spec.add_development_dependency "pry"
|
35
|
+
spec.add_development_dependency "bundler", "~> 1.9"
|
36
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
37
|
+
|
38
|
+
spec.add_development_dependency "fakefs", "~> 0.4"
|
39
|
+
spec.add_development_dependency "minitest"
|
40
|
+
spec.add_development_dependency "mocha", "~> 1.1"
|
41
|
+
|
42
|
+
spec.add_development_dependency "countloc", "~> 0.4"
|
43
|
+
spec.add_development_dependency "maruku", "~> 0.6"
|
44
|
+
spec.add_development_dependency "simplecov", "~> 0.7"
|
45
|
+
spec.add_development_dependency "yard", "~> 0.8"
|
46
|
+
|
47
|
+
# style and complexity libraries are tightly version pinned as newer releases
|
48
|
+
# may introduce new and undesireable style choices which would be immediately
|
49
|
+
# enforced in CI
|
50
|
+
spec.add_development_dependency "finstyle", "1.4.0"
|
51
|
+
spec.add_development_dependency "cane", "2.6.2"
|
52
|
+
end
|