ruby-pwsh 1.1.1 → 1.2.1
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 +5 -0
- data/lib/puppet/provider/dsc_base_provider/dsc_base_provider.rb +26 -5
- data/lib/pwsh/util.rb +10 -14
- data/lib/pwsh/version.rb +1 -1
- data/lib/pwsh.rb +2 -2
- data/spec/unit/puppet/provider/dsc_base_provider/dsc_base_provider_spec.rb +62 -19
- data/spec/unit/pwsh/util_spec.rb +42 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 106716635e03eef49ab00c8dd35cf16a5674a27452968b16ba7756ba252b97be
|
4
|
+
data.tar.gz: 4bd6c34343347a1d705cea410346028bbb91446bf5983e75409f16c7730f1000
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f8b6c0c4ff6eabbc9a842cc863d76128dbccca74fabfef02b4aea6ba54f3a01ffd3d97447df4ccc027a8f22cf6a7b430b0893e34d0de7989e742442cf56b5ef9
|
7
|
+
data.tar.gz: 2404be74308d1b80c5d8f775f49f0f0ac6ae7deab47fe7c38e25e79852aac42f87e16b5cea5e4a4617cdde6eac1236cc8407a0e10fe2c9198bcfd0d6e88a7548
|
data/README.md
CHANGED
@@ -85,6 +85,11 @@ The following platforms are supported:
|
|
85
85
|
- OSX
|
86
86
|
- RedHat
|
87
87
|
- Ubuntu
|
88
|
+
- AlmaLinux
|
89
|
+
|
90
|
+
## Limitations
|
91
|
+
|
92
|
+
- When PowerShell [Script Block Logging](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_logging_windows?view=powershell-7.4#enabling-script-block-logging) is enabled, data marked as sensitive in your manifest may appear in these logs as plain text. It is **highly recommended**, by both Puppet and Microsoft, that you also enable [Protected Event Logging](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_logging_windows?view=powershell-7.4#protected-event-logging) alongside this to encrypt the logs to protect this information.
|
88
93
|
|
89
94
|
## License
|
90
95
|
|
@@ -15,6 +15,7 @@ class Puppet::Provider::DscBaseProvider # rubocop:disable Metrics/ClassLength
|
|
15
15
|
@cached_query_results = []
|
16
16
|
@cached_test_results = []
|
17
17
|
@logon_failures = []
|
18
|
+
@timeout = nil # default timeout, ps_manager.execute is expecting nil by default..
|
18
19
|
super
|
19
20
|
end
|
20
21
|
|
@@ -251,18 +252,22 @@ class Puppet::Provider::DscBaseProvider # rubocop:disable Metrics/ClassLength
|
|
251
252
|
context.err('Logon credentials are invalid')
|
252
253
|
return nil
|
253
254
|
end
|
255
|
+
specify_dsc_timeout(name_hash)
|
254
256
|
resource = invocable_resource(props, context, method)
|
255
257
|
script_content = ps_script_content(resource)
|
258
|
+
context.debug("Invoke-DSC Timeout: #{@timeout} milliseconds") if @timeout
|
256
259
|
context.debug("Script:\n #{redact_secrets(script_content)}")
|
257
|
-
output = ps_manager.execute(remove_secret_identifiers(script_content))
|
260
|
+
output = ps_manager.execute(remove_secret_identifiers(script_content), @timeout)
|
258
261
|
|
259
|
-
if output.nil?
|
260
|
-
|
262
|
+
if output[:stdout].nil?
|
263
|
+
message = 'Nothing returned.'
|
264
|
+
message += " #{output[:errormessage]}" if output[:errormessage]&.match?(/PowerShell module timeout \(\d+ ms\) exceeded while executing/)
|
265
|
+
context.err(message)
|
261
266
|
return nil
|
262
267
|
end
|
263
268
|
|
264
269
|
begin
|
265
|
-
data = JSON.parse(output)
|
270
|
+
data = JSON.parse(output[:stdout])
|
266
271
|
rescue StandardError => e
|
267
272
|
context.err(e)
|
268
273
|
return nil
|
@@ -295,6 +300,18 @@ class Puppet::Provider::DscBaseProvider # rubocop:disable Metrics/ClassLength
|
|
295
300
|
data
|
296
301
|
end
|
297
302
|
|
303
|
+
# Sets the @timeout instance variable.
|
304
|
+
# @param name_hash [Hash] the hash of namevars to be passed as properties to `Invoke-DscResource`
|
305
|
+
# The @timeout variable is set to the value of name_hash[:dsc_timeout] in milliseconds
|
306
|
+
# If name_hash[:dsc_timeout] is nil, @timeout is not changed.
|
307
|
+
# If @timeout is already set to a value other than nil,
|
308
|
+
# it is changed only if it's different from name_hash[:dsc_timeout]..
|
309
|
+
def specify_dsc_timeout(name_hash)
|
310
|
+
return unless name_hash[:dsc_timeout] && (@timeout.nil? || @timeout != name_hash[:dsc_timeout])
|
311
|
+
|
312
|
+
@timeout = name_hash[:dsc_timeout] * 1000
|
313
|
+
end
|
314
|
+
|
298
315
|
# Retries Invoke-DscResource when returned error matches error regex supplied as param.
|
299
316
|
# @param context [Object] the Puppet runtime context to operate in and send feedback to
|
300
317
|
# @param max_retry_count [Int] max number of times to retry Invoke-DscResource
|
@@ -1076,6 +1093,10 @@ class Puppet::Provider::DscBaseProvider # rubocop:disable Metrics/ClassLength
|
|
1076
1093
|
def ps_manager
|
1077
1094
|
debug_output = Puppet::Util::Log.level == :debug
|
1078
1095
|
# TODO: Allow you to specify an alternate path, either to pwsh generally or a specific pwsh path.
|
1079
|
-
|
1096
|
+
if Pwsh::Util.on_windows?
|
1097
|
+
Pwsh::Manager.instance(Pwsh::Manager.powershell_path, Pwsh::Manager.powershell_args, debug: debug_output)
|
1098
|
+
else
|
1099
|
+
Pwsh::Manager.instance(Pwsh::Manager.pwsh_path, Pwsh::Manager.pwsh_args, debug: debug_output)
|
1100
|
+
end
|
1080
1101
|
end
|
1081
1102
|
end
|
data/lib/pwsh/util.rb
CHANGED
@@ -7,28 +7,24 @@ module Pwsh
|
|
7
7
|
module_function
|
8
8
|
|
9
9
|
# Verifies whether or not the current context is running on a Windows node.
|
10
|
+
# Implementation copied from `facets`: https://github.com/rubyworks/facets/blob/main/lib/standard/facets/rbconfig.rb
|
10
11
|
#
|
11
12
|
# @return [Bool] true if on windows
|
12
13
|
def on_windows?
|
13
|
-
|
14
|
-
|
15
|
-
!!File::ALT_SEPARATOR
|
14
|
+
host_os = RbConfig::CONFIG['host_os']
|
15
|
+
!!(host_os =~ /mswin|mingw/)
|
16
16
|
end
|
17
17
|
|
18
|
-
# Verify paths specified are valid directories
|
19
|
-
#
|
20
|
-
# @return [Bool] true if any
|
18
|
+
# Verify paths specified are valid directories.
|
19
|
+
# Skips paths which do not exist.
|
20
|
+
# @return [Bool] true if any paths specified are not valid directories
|
21
21
|
def invalid_directories?(path_collection)
|
22
|
-
|
23
|
-
|
24
|
-
return invalid_paths if path_collection.nil? || path_collection.empty?
|
22
|
+
return false if path_collection.nil? || path_collection.empty?
|
25
23
|
|
26
|
-
|
27
|
-
paths
|
28
|
-
invalid_paths = true unless File.directory?(path) || path.empty?
|
29
|
-
end
|
24
|
+
delimiter = on_windows? ? ';' : ':'
|
25
|
+
paths = path_collection.split(delimiter)
|
30
26
|
|
31
|
-
|
27
|
+
paths.any? { |path| !path.empty? && File.exist?(path) && !File.directory?(path) }
|
32
28
|
end
|
33
29
|
|
34
30
|
# Return a string or symbol converted to snake_case
|
data/lib/pwsh/version.rb
CHANGED
data/lib/pwsh.rb
CHANGED
@@ -108,7 +108,7 @@ module Pwsh
|
|
108
108
|
@powershell_command = cmd
|
109
109
|
@powershell_arguments = args
|
110
110
|
|
111
|
-
|
111
|
+
warn "Bad configuration for ENV['lib']=#{ENV['lib']} - invalid path" if Pwsh::Util.invalid_directories?(ENV['lib'])
|
112
112
|
|
113
113
|
if Pwsh::Util.on_windows?
|
114
114
|
# Named pipes under Windows will automatically be mounted in \\.\pipe\...
|
@@ -380,7 +380,7 @@ module Pwsh
|
|
380
380
|
pwsh_paths << File.join(path, 'pwsh.exe') if File.exist?(File.join(path, 'pwsh.exe'))
|
381
381
|
end
|
382
382
|
else
|
383
|
-
search_paths.split(
|
383
|
+
search_paths.split(':').each do |path|
|
384
384
|
pwsh_paths << File.join(path, 'pwsh') if File.exist?(File.join(path, 'pwsh'))
|
385
385
|
end
|
386
386
|
end
|
@@ -541,7 +541,7 @@ RSpec.describe Puppet::Provider::DscBaseProvider do
|
|
541
541
|
|
542
542
|
context 'when the invocation script returns data without errors' do
|
543
543
|
before do
|
544
|
-
allow(ps_manager).to receive(:execute).with(script).and_return({ stdout: 'DSC Data' })
|
544
|
+
allow(ps_manager).to receive(:execute).with(script, nil).and_return({ stdout: 'DSC Data' })
|
545
545
|
allow(JSON).to receive(:parse).with('DSC Data').and_return(parsed_invocation_data)
|
546
546
|
allow(Puppet::Pops::Time::Timestamp).to receive(:parse).with('2100-01-01').and_return('TimeStamp:2100-01-01')
|
547
547
|
allow(provider).to receive(:fetch_cached_hashes).and_return([])
|
@@ -659,15 +659,15 @@ RSpec.describe Puppet::Provider::DscBaseProvider do
|
|
659
659
|
context 'when the DSC invocation errors' do
|
660
660
|
it 'writes an error and returns nil' do
|
661
661
|
expect(provider).not_to receive(:logon_failed_already?)
|
662
|
-
expect(ps_manager).to receive(:execute).with(script).and_return({ stdout: nil })
|
663
|
-
expect(context).to receive(:err).with('Nothing returned')
|
662
|
+
expect(ps_manager).to receive(:execute).with(script, nil).and_return({ stdout: nil })
|
663
|
+
expect(context).to receive(:err).with('Nothing returned.')
|
664
664
|
expect(result).to be_nil
|
665
665
|
end
|
666
666
|
end
|
667
667
|
|
668
668
|
context 'when handling DateTimes' do
|
669
669
|
before do
|
670
|
-
allow(ps_manager).to receive(:execute).with(script).and_return({ stdout: 'DSC Data' })
|
670
|
+
allow(ps_manager).to receive(:execute).with(script, nil).and_return({ stdout: 'DSC Data' })
|
671
671
|
allow(JSON).to receive(:parse).with('DSC Data').and_return(parsed_invocation_data)
|
672
672
|
allow(provider).to receive(:fetch_cached_hashes).and_return([])
|
673
673
|
end
|
@@ -719,7 +719,7 @@ RSpec.describe Puppet::Provider::DscBaseProvider do
|
|
719
719
|
context 'when the credential is invalid' do
|
720
720
|
before do
|
721
721
|
allow(provider).to receive(:logon_failed_already?).and_return(false)
|
722
|
-
allow(ps_manager).to receive(:execute).with(script).and_return({ stdout: 'DSC Data' })
|
722
|
+
allow(ps_manager).to receive(:execute).with(script, nil).and_return({ stdout: 'DSC Data' })
|
723
723
|
allow(JSON).to receive(:parse).with('DSC Data').and_return({ 'errormessage' => dsc_logon_failure_error })
|
724
724
|
allow(context).to receive(:err).with(name_hash[:name], puppet_logon_failure_error)
|
725
725
|
end
|
@@ -783,7 +783,7 @@ RSpec.describe Puppet::Provider::DscBaseProvider do
|
|
783
783
|
context 'when the invocation script returns nil' do
|
784
784
|
it 'errors via context but does not raise' do
|
785
785
|
expect(ps_manager).to receive(:execute).and_return({ stdout: nil })
|
786
|
-
expect(context).to receive(:err).with('Nothing returned')
|
786
|
+
expect(context).to receive(:err).with('Nothing returned.')
|
787
787
|
expect { result }.not_to raise_error
|
788
788
|
end
|
789
789
|
end
|
@@ -835,9 +835,29 @@ RSpec.describe Puppet::Provider::DscBaseProvider do
|
|
835
835
|
end
|
836
836
|
end
|
837
837
|
|
838
|
+
context 'when a dsc_timeout is specified' do
|
839
|
+
let(:should_hash) { name.merge(dsc_timeout: 5) }
|
840
|
+
let(:apply_props_with_timeout) { { dsc_name: 'foo', dsc_timeout: 5 } }
|
841
|
+
let(:resource_with_timeout) { "Resource: #{apply_props_with_timeout}" }
|
842
|
+
let(:script_with_timeout) { "Script: #{apply_props_with_timeout}" }
|
843
|
+
|
844
|
+
before do
|
845
|
+
allow(provider).to receive(:invocable_resource).with(apply_props_with_timeout, context, 'set').and_return(resource_with_timeout)
|
846
|
+
allow(provider).to receive(:ps_script_content).with(resource_with_timeout).and_return(script_with_timeout)
|
847
|
+
allow(provider).to receive(:remove_secret_identifiers).with(script_with_timeout).and_return(script_with_timeout)
|
848
|
+
end
|
849
|
+
|
850
|
+
it 'sets @timeout and passes it to ps_manager.execute' do
|
851
|
+
provider.instance_variable_set(:@timeout, nil)
|
852
|
+
expect(ps_manager).to receive(:execute).with(script_with_timeout, 5000).and_return({ stdout: '{"in_desired_state": true, "errormessage": null}' })
|
853
|
+
provider.invoke_set_method(context, name, should_hash)
|
854
|
+
expect(provider.instance_variable_get(:@timeout)).to eq(5000)
|
855
|
+
end
|
856
|
+
end
|
857
|
+
|
838
858
|
context 'when the invocation script returns data without errors' do
|
839
859
|
it 'filters for the correct properties to invoke and returns the results' do
|
840
|
-
expect(ps_manager).to receive(:execute).with("Script: #{apply_props}").and_return({ stdout: '{"in_desired_state": true, "errormessage": null}' })
|
860
|
+
expect(ps_manager).to receive(:execute).with("Script: #{apply_props}", nil).and_return({ stdout: '{"in_desired_state": true, "errormessage": null}' })
|
841
861
|
expect(context).not_to receive(:err)
|
842
862
|
expect(result).to eq({ 'in_desired_state' => true, 'errormessage' => nil })
|
843
863
|
end
|
@@ -2110,21 +2130,44 @@ RSpec.describe Puppet::Provider::DscBaseProvider do
|
|
2110
2130
|
end
|
2111
2131
|
|
2112
2132
|
describe '.ps_manager' do
|
2113
|
-
|
2114
|
-
|
2115
|
-
|
2116
|
-
|
2133
|
+
describe '.ps_manager on non-Windows' do
|
2134
|
+
before do
|
2135
|
+
allow(Pwsh::Util).to receive(:on_windows?).and_return(false)
|
2136
|
+
allow(Pwsh::Manager).to receive(:pwsh_path).and_return('pwsh')
|
2137
|
+
allow(Pwsh::Manager).to receive(:pwsh_args).and_return('args')
|
2138
|
+
end
|
2139
|
+
|
2140
|
+
it 'Initializes an instance of the Pwsh::Manager' do
|
2141
|
+
expect(Puppet::Util::Log).to receive(:level).and_return(:normal)
|
2142
|
+
expect(Pwsh::Manager).to receive(:instance).with('pwsh', 'args', debug: false)
|
2143
|
+
expect { provider.ps_manager }.not_to raise_error
|
2144
|
+
end
|
2117
2145
|
|
2118
|
-
|
2119
|
-
|
2120
|
-
|
2121
|
-
|
2146
|
+
it 'passes debug as true if Puppet::Util::Log.level is debug' do
|
2147
|
+
expect(Puppet::Util::Log).to receive(:level).and_return(:debug)
|
2148
|
+
expect(Pwsh::Manager).to receive(:instance).with('pwsh', 'args', debug: true)
|
2149
|
+
expect { provider.ps_manager }.not_to raise_error
|
2150
|
+
end
|
2122
2151
|
end
|
2123
2152
|
|
2124
|
-
|
2125
|
-
|
2126
|
-
|
2127
|
-
|
2153
|
+
describe '.ps_manager on Windows' do
|
2154
|
+
before do
|
2155
|
+
allow(Pwsh::Util).to receive(:on_windows?).and_return(true)
|
2156
|
+
allow(Pwsh::Manager).to receive(:powershell_path).and_return('pwsh')
|
2157
|
+
allow(Pwsh::Manager).to receive(:powershell_args).and_return('args')
|
2158
|
+
end
|
2159
|
+
|
2160
|
+
it 'Initializes an instance of the Pwsh::Manager' do
|
2161
|
+
expect(Puppet::Util::Log).to receive(:level).and_return(:normal)
|
2162
|
+
expect(Pwsh::Manager).to receive(:instance).with('pwsh', 'args', debug: false)
|
2163
|
+
expect { provider.ps_manager }.not_to raise_error
|
2164
|
+
end
|
2165
|
+
|
2166
|
+
it 'passes debug as true if Puppet::Util::Log.level is debug' do
|
2167
|
+
expect(Puppet::Util::Log).to receive(:level).and_return(:debug)
|
2168
|
+
expect(Pwsh::Manager).to receive(:instance).with('pwsh', 'args', debug: true)
|
2169
|
+
expect { provider.ps_manager }.not_to raise_error
|
2170
|
+
end
|
2128
2171
|
end
|
2129
2172
|
end
|
2130
2173
|
end
|
data/spec/unit/pwsh/util_spec.rb
CHANGED
@@ -87,13 +87,15 @@ RSpec.describe Pwsh::Util do
|
|
87
87
|
end
|
88
88
|
|
89
89
|
describe '.invalid_directories?' do
|
90
|
-
let(:valid_path_a)
|
91
|
-
let(:valid_path_b)
|
92
|
-
let(:valid_paths)
|
93
|
-
let(:invalid_path)
|
94
|
-
let(:mixed_paths)
|
95
|
-
let(:empty_string)
|
96
|
-
let(:
|
90
|
+
let(:valid_path_a) { 'C:/some/folder' }
|
91
|
+
let(:valid_path_b) { 'C:/another/folder' }
|
92
|
+
let(:valid_paths) { 'C:/some/folder;C:/another/folder' }
|
93
|
+
let(:invalid_path) { 'C:/invalid/path' }
|
94
|
+
let(:mixed_paths) { 'C:/some/folder;C:/another/folder;C:/invalid/path' }
|
95
|
+
let(:empty_string) { '' }
|
96
|
+
let(:file_path) { 'C:/some/folder/file.txt' }
|
97
|
+
let(:non_existent_dir) { 'C:/some/dir/that/doesnt/exist' }
|
98
|
+
let(:empty_members) { 'C:/some/folder;;C:/another/folder' }
|
97
99
|
|
98
100
|
it 'returns false if passed nil' do
|
99
101
|
expect(described_class.invalid_directories?(nil)).to be false
|
@@ -103,8 +105,16 @@ RSpec.describe Pwsh::Util do
|
|
103
105
|
expect(described_class.invalid_directories?('')).to be false
|
104
106
|
end
|
105
107
|
|
108
|
+
it 'returns true if a file path is provided' do
|
109
|
+
expect(described_class).to receive(:on_windows?).and_return(true)
|
110
|
+
expect(File).to receive(:exist?).with(file_path).and_return(true)
|
111
|
+
expect(File).to receive(:directory?).with(file_path).and_return(false)
|
112
|
+
expect(described_class.invalid_directories?(file_path)).to be true
|
113
|
+
end
|
114
|
+
|
106
115
|
it 'returns false if one valid path is provided' do
|
107
116
|
expect(described_class).to receive(:on_windows?).and_return(true)
|
117
|
+
expect(File).to receive(:exist?).with(valid_path_a).and_return(true)
|
108
118
|
expect(File).to receive(:directory?).with(valid_path_a).and_return(true)
|
109
119
|
expect(described_class.invalid_directories?(valid_path_a)).to be false
|
110
120
|
end
|
@@ -112,31 +122,56 @@ RSpec.describe Pwsh::Util do
|
|
112
122
|
it 'returns false if a collection of valid paths is provided' do
|
113
123
|
expect(described_class).to receive(:on_windows?).and_return(true)
|
114
124
|
expect(File).to receive(:directory?).with(valid_path_a).and_return(true)
|
125
|
+
expect(File).to receive(:exist?).with(valid_path_a).and_return(true)
|
115
126
|
expect(File).to receive(:directory?).with(valid_path_b).and_return(true)
|
127
|
+
expect(File).to receive(:exist?).with(valid_path_b).and_return(true)
|
116
128
|
expect(described_class.invalid_directories?(valid_paths)).to be false
|
117
129
|
end
|
118
130
|
|
119
131
|
it 'returns true if there is only one path and it is invalid' do
|
120
132
|
expect(described_class).to receive(:on_windows?).and_return(true)
|
133
|
+
expect(File).to receive(:exist?).with(invalid_path).and_return(true)
|
121
134
|
expect(File).to receive(:directory?).with(invalid_path).and_return(false)
|
122
135
|
expect(described_class.invalid_directories?(invalid_path)).to be true
|
123
136
|
end
|
124
137
|
|
125
138
|
it 'returns true if the collection has on valid and one invalid member' do
|
126
139
|
expect(described_class).to receive(:on_windows?).and_return(true)
|
140
|
+
expect(File).to receive(:exist?).with(valid_path_a).and_return(true)
|
127
141
|
expect(File).to receive(:directory?).with(valid_path_a).and_return(true)
|
142
|
+
expect(File).to receive(:exist?).with(valid_path_b).and_return(true)
|
128
143
|
expect(File).to receive(:directory?).with(valid_path_b).and_return(true)
|
144
|
+
expect(File).to receive(:exist?).with(invalid_path).and_return(true)
|
129
145
|
expect(File).to receive(:directory?).with(invalid_path).and_return(false)
|
130
146
|
expect(described_class.invalid_directories?(mixed_paths)).to be true
|
131
147
|
end
|
132
148
|
|
133
149
|
it 'returns false if collection has empty members but other entries are valid' do
|
134
150
|
expect(described_class).to receive(:on_windows?).and_return(true)
|
151
|
+
expect(File).to receive(:exist?).with(valid_path_a).and_return(true)
|
135
152
|
expect(File).to receive(:directory?).with(valid_path_a).and_return(true)
|
153
|
+
expect(File).to receive(:exist?).with(valid_path_b).and_return(true)
|
136
154
|
expect(File).to receive(:directory?).with(valid_path_b).and_return(true)
|
137
155
|
allow(File).to receive(:directory?).with('')
|
138
156
|
expect(described_class.invalid_directories?(empty_members)).to be false
|
139
157
|
end
|
158
|
+
|
159
|
+
it 'returns true if a collection has valid members but also contains a file path' do
|
160
|
+
expect(described_class).to receive(:on_windows?).and_return(true)
|
161
|
+
expect(File).to receive(:exist?).with(valid_path_a).and_return(true)
|
162
|
+
expect(File).to receive(:directory?).with(valid_path_a).and_return(true)
|
163
|
+
expect(File).to receive(:exist?).with(file_path).and_return(true)
|
164
|
+
expect(File).to receive(:directory?).with(file_path).and_return(false)
|
165
|
+
expect(described_class.invalid_directories?("#{valid_path_a};#{file_path}")).to be true
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'returns false if a collection has valid members but contains a non-existent dir path' do
|
169
|
+
expect(described_class).to receive(:on_windows?).and_return(true)
|
170
|
+
expect(File).to receive(:exist?).with(valid_path_a).and_return(true)
|
171
|
+
expect(File).to receive(:directory?).with(valid_path_a).and_return(true)
|
172
|
+
expect(File).to receive(:exist?).with(non_existent_dir).and_return(false)
|
173
|
+
expect(described_class.invalid_directories?("#{valid_path_a};#{non_existent_dir}")).to be false
|
174
|
+
end
|
140
175
|
end
|
141
176
|
|
142
177
|
describe '.snake_case' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-pwsh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-09-20 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: PowerShell code manager for ruby.
|
14
14
|
email:
|