ruby-pwsh 1.1.1 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|