chef-winrm-fs 1.4.2 → 1.4.4

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.
@@ -1,178 +1,176 @@
1
- # frozen_string_literal: true
2
-
3
- #
4
- # Author:: Fletcher (<fnichol@nichol.ca>)
5
- #
6
- # Copyright (C) 2015, Fletcher Nichol
7
- #
8
- # Licensed under the Apache License, Version 2.0 (the "License");
9
- # you may not use this file except in compliance with the License.
10
- # You may obtain a copy of the License at
11
- #
12
- # http://www.apache.org/licenses/LICENSE-2.0
13
- #
14
- # Unless required by applicable law or agreed to in writing, software
15
- # distributed under the License is distributed on an "AS IS" BASIS,
16
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
- # See the License for the specific language governing permissions and
18
- # limitations under the License.
19
-
20
- require "delegate"
21
- require "pathname" unless defined?(Pathname)
22
- require "tempfile" unless defined?(Tempfile)
23
- require "zip" unless defined?(Zip)
24
-
25
- module WinRM
26
- module FS
27
- module Core
28
- # A temporary Zip file for a given directory.
29
- #
30
- # @author Fletcher Nichol <fnichol@nichol.ca>
31
- class TmpZip
32
- # Contructs a new Zip file for the given directory.
33
- #
34
- # There are 2 ways to interpret the directory path:
35
- #
36
- # * If the directory has no path separator terminator, then the
37
- # directory basename will be used as the base directory in the
38
- # resulting zip file.
39
- # * If the directory has a path separator terminator (such as `/` or
40
- # `\\`), then the entries under the directory will be added to the
41
- # resulting zip file.
42
- #
43
- # The following emaples assume a directory tree structure of:
44
- #
45
- # src
46
- # |-- alpha.txt
47
- # |-- beta.txt
48
- # \-- sub
49
- # \-- charlie.txt
50
- #
51
- # @example Including the base directory in the zip file
52
- #
53
- # TmpZip.new("/path/to/src")
54
- # # produces a zip file with entries:
55
- # # - src/alpha.txt
56
- # # - src/beta.txt
57
- # # - src/sub/charlie.txt
58
- #
59
- # @example Excluding the base directory in the zip file
60
- #
61
- # TmpZip.new("/path/to/src/")
62
- # # produces a zip file with entries:
63
- # # - alpha.txt
64
- # # - beta.txt
65
- # # - sub/charlie.txt
66
- #
67
- # @param dir [String,Pathname,#to_s] path to the directory
68
- # @param logger [#debug,#debug?] an optional logger/ui object that
69
- # responds to `#debug` and `#debug?` (default `nil`)
70
- def initialize(dir, logger = nil)
71
- @logger = logger || Logging.logger[self]
72
- @dir = clean_dirname(dir)
73
- @zip_io = Tempfile.open(["tmpzip-", ".zip"], binmode: true)
74
- write_zip
75
- @zip_io.close
76
- end
77
-
78
- # @return [Pathname] path to zip file
79
- def path
80
- Pathname.new(zip_io.path) if zip_io.path
81
- end
82
-
83
- # Unlinks (deletes) the zip file from the filesystem.
84
- def unlink
85
- zip_io.unlink
86
- end
87
-
88
- private
89
-
90
- # @return [Pathname] the directory used to create the Zip file
91
- # @api private
92
- attr_reader :dir
93
-
94
- # @return [#debug] the logger
95
- # @api private
96
- attr_reader :logger
97
-
98
- # @return [IO] the Zip file IO
99
- # @api private
100
- attr_reader :zip_io
101
-
102
- # @return [Pathname] the pathname object representing dirname that
103
- # doesn't have any of those ~ in it
104
- # @api private
105
- def clean_dirname(dir)
106
- paths = Pathname.glob(dir)
107
- raise "Expected Pathname.glob(dir) to return only dir, got #{paths}" if paths.length != 1
108
-
109
- paths.first
110
- end
111
-
112
- # @return [Array<Pathname] all recursive files under the base
113
- # directory, excluding directories
114
- # @api private
115
- def entries
116
- Pathname.glob(dir.join("**/.*")).push(*Pathname.glob(dir.join("**/*"))).delete_if(&:directory?).sort
117
- end
118
-
119
- # (see Logging.log_subject)
120
- # @api private
121
- def log_subject
122
- @log_subject ||= [self.class.to_s.split("::").last, path].join("::")
123
- end
124
-
125
- # Adds all file entries to the Zip output stream.
126
- #
127
- # @param zos [Zip::OutputStream] zip output stream
128
- # @api private
129
- def produce_zip_entries(zos)
130
- entries.each do |entry|
131
- entry_path = entry.relative_path_from(dir)
132
- logger.debug "+++ Adding #{entry_path}"
133
- zos.put_next_entry(
134
- zip_entry(entry_path),
135
- nil, nil, ::Zip::Entry::DEFLATED, Zlib::BEST_COMPRESSION
136
- )
137
- entry.open("rb") { |src| IO.copy_stream(src, zos) }
138
- end
139
- logger.debug "=== All files added."
140
- end
141
-
142
- # Writes out a temporary Zip file.
143
- #
144
- # @api private
145
- def write_zip
146
- logger.debug "Populating files"
147
- Zip::OutputStream.write_buffer(NoDupIO.new(zip_io)) do |zos|
148
- produce_zip_entries(zos)
149
- end
150
- end
151
-
152
- def zip_entry(entry_path)
153
- Zip::Entry.new(
154
- zip_io.path,
155
- entry_path.to_s,
156
- nil, nil, nil, nil, nil, nil,
157
- ::Zip::DOSTime.new(2000)
158
- )
159
- end
160
-
161
- # Simple delegate wrapper to prevent `#dup` calls being made on IO
162
- # objects. This is used to bypass an issue in the `Zip::Outputstream`
163
- # constructor where an incoming IO is duplicated, leading to races
164
- # on flushing the final stream to disk.
165
- #
166
- # @author Fletcher Nichol <fnichol@nichol.ca>
167
- # @api private
168
- class NoDupIO < SimpleDelegator
169
- # @return [self] returns self and does *not* return a duplicate
170
- # object
171
- def dup
172
- self
173
- end
174
- end
175
- end
176
- end
177
- end
178
- end
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Author:: Fletcher (<fnichol@nichol.ca>)
5
+ #
6
+ # Copyright (C) 2015, Fletcher Nichol
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+
20
+ require "delegate"
21
+ require "pathname" unless defined?(Pathname)
22
+ require "tempfile" unless defined?(Tempfile)
23
+
24
+ module WinRM
25
+ module FS
26
+ module Core
27
+ # A temporary Zip file for a given directory.
28
+ #
29
+ # @author Fletcher Nichol <fnichol@nichol.ca>
30
+ class TmpZip
31
+ # Contructs a new Zip file for the given directory.
32
+ #
33
+ # There are 2 ways to interpret the directory path:
34
+ #
35
+ # * If the directory has no path separator terminator, then the
36
+ # directory basename will be used as the base directory in the
37
+ # resulting zip file.
38
+ # * If the directory has a path separator terminator (such as `/` or
39
+ # `\\`), then the entries under the directory will be added to the
40
+ # resulting zip file.
41
+ #
42
+ # The following emaples assume a directory tree structure of:
43
+ #
44
+ # src
45
+ # |-- alpha.txt
46
+ # |-- beta.txt
47
+ # \-- sub
48
+ # \-- charlie.txt
49
+ #
50
+ # @example Including the base directory in the zip file
51
+ #
52
+ # TmpZip.new("/path/to/src")
53
+ # # produces a zip file with entries:
54
+ # # - src/alpha.txt
55
+ # # - src/beta.txt
56
+ # # - src/sub/charlie.txt
57
+ #
58
+ # @example Excluding the base directory in the zip file
59
+ #
60
+ # TmpZip.new("/path/to/src/")
61
+ # # produces a zip file with entries:
62
+ # # - alpha.txt
63
+ # # - beta.txt
64
+ # # - sub/charlie.txt
65
+ #
66
+ # @param dir [String,Pathname,#to_s] path to the directory
67
+ # @param logger [#debug,#debug?] an optional logger/ui object that
68
+ # responds to `#debug` and `#debug?` (default `nil`)
69
+ def initialize(dir, logger = nil)
70
+ require "zip" unless defined?(Zip)
71
+ @logger = logger || Logging.logger[self]
72
+ @dir = clean_dirname(dir)
73
+ @zip_io = Tempfile.open(["tmpzip-", ".zip"], binmode: true)
74
+ write_zip
75
+ @zip_io.close
76
+ end
77
+
78
+ # @return [Pathname] path to zip file
79
+ def path
80
+ Pathname.new(zip_io.path) if zip_io.path
81
+ end
82
+
83
+ # Unlinks (deletes) the zip file from the filesystem.
84
+ def unlink
85
+ zip_io.unlink
86
+ end
87
+
88
+ private
89
+
90
+ # @return [Pathname] the directory used to create the Zip file
91
+ # @api private
92
+ attr_reader :dir
93
+
94
+ # @return [#debug] the logger
95
+ # @api private
96
+ attr_reader :logger
97
+
98
+ # @return [IO] the Zip file IO
99
+ # @api private
100
+ attr_reader :zip_io
101
+
102
+ # @return [Pathname] the pathname object representing dirname that
103
+ # doesn't have any of those ~ in it
104
+ # @api private
105
+ def clean_dirname(dir)
106
+ paths = Pathname.glob(dir)
107
+ raise "Expected Pathname.glob(dir) to return only dir, got #{paths}" if paths.length != 1
108
+
109
+ paths.first
110
+ end
111
+
112
+ # @return [Array<Pathname] all recursive files under the base
113
+ # directory, excluding directories
114
+ # @api private
115
+ def entries
116
+ Pathname.glob(dir.join("**/.*")).push(*Pathname.glob(dir.join("**/*"))).delete_if(&:directory?).sort
117
+ end
118
+
119
+ # (see Logging.log_subject)
120
+ # @api private
121
+ def log_subject
122
+ @log_subject ||= [self.class.to_s.split("::").last, path].join("::")
123
+ end
124
+
125
+ # Adds all file entries to the Zip output stream.
126
+ #
127
+ # @param zos [Zip::OutputStream] zip output stream
128
+ # @api private
129
+ def produce_zip_entries(zos)
130
+ entries.each do |entry|
131
+ entry_path = entry.relative_path_from(dir)
132
+ logger.debug "+++ Adding #{entry_path}"
133
+ zos.put_next_entry(zip_entry(entry_path))
134
+ entry.open("rb") { |src| IO.copy_stream(src, zos) }
135
+ end
136
+ logger.debug "=== All files added."
137
+ end
138
+
139
+ # Writes out a temporary Zip file.
140
+ #
141
+ # @api private
142
+ def write_zip
143
+ logger.debug "Populating files"
144
+ Zip::OutputStream.write_buffer(NoDupIO.new(zip_io)) do |zos|
145
+ produce_zip_entries(zos)
146
+ end
147
+ end
148
+
149
+ def zip_entry(entry_path)
150
+ Zip::Entry.new(
151
+ zip_io.path,
152
+ entry_path.to_s,
153
+ compression_method: ::Zip::Entry::DEFLATED,
154
+ compression_level: Zlib::BEST_COMPRESSION,
155
+ time: ::Zip::DOSTime.new(2000)
156
+ )
157
+ end
158
+
159
+ # Simple delegate wrapper to prevent `#dup` calls being made on IO
160
+ # objects. This is used to bypass an issue in the `Zip::Outputstream`
161
+ # constructor where an incoming IO is duplicated, leading to races
162
+ # on flushing the final stream to disk.
163
+ #
164
+ # @author Fletcher Nichol <fnichol@nichol.ca>
165
+ # @api private
166
+ class NoDupIO < SimpleDelegator
167
+ # @return [self] returns self and does *not* return a duplicate
168
+ # object
169
+ def dup
170
+ self
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
@@ -1,29 +1,29 @@
1
- # frozen_string_literal: true
2
-
3
- #
4
- # Copyright 2015 Shawn Neal <sneal@sneal.net>
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
-
18
- module WinRM
19
- module FS
20
- # WinRM-FS base class for errors
21
- class WinRMFSError < StandardError; end
22
-
23
- # Error that occurs when a file upload fails
24
- class WinRMUploadError < WinRMFSError; end
25
-
26
- # Error that occurs when a file download fails
27
- class WinRMDownloadError < WinRMFSError; end
28
- end
29
- end
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright 2015 Shawn Neal <sneal@sneal.net>
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ module WinRM
19
+ module FS
20
+ # WinRM-FS base class for errors
21
+ class WinRMFSError < StandardError; end
22
+
23
+ # Error that occurs when a file upload fails
24
+ class WinRMUploadError < WinRMFSError; end
25
+
26
+ # Error that occurs when a file download fails
27
+ class WinRMDownloadError < WinRMFSError; end
28
+ end
29
+ end