ruby-pwsh 0.10.2 → 0.11.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c0192c9fd1e6f719c01cfbc185c847943ec0878c1fbfda56749a52dfd5d7fca7
4
- data.tar.gz: 5d40c16d7f2efe2585a0c65d0e6050aaa72e4083510cbac376038a85ec725264
3
+ metadata.gz: a3357d3c933ddf7b2ecce5d3be1958e9d6aaf6b9966f0b4e4d1f45c40f13963c
4
+ data.tar.gz: 59e415fc5c1804e09c481bfb6a3c8aa58a7b9767dd04f0a31b3f65c6986ab9c0
5
5
  SHA512:
6
- metadata.gz: 1e1356eb57e96fa78906861bdd6bf887c5f9eb14175f5408e4db779a3b66ac1bc9bf92d1436f36d019da8b3e18f0bfbc175170d8e3058eff6c3e51235b433ac0
7
- data.tar.gz: de4bdce317e05453eb9179df50f065c09c16da4529b304ed0adb7e4becc3c8378ea0f67d69444209ac72d6a5f19881b594f624c311412e8fa32fdcb4bdb9b34d
6
+ metadata.gz: dd03304fb4b624296d2770b33296464ca7968e0d1f3b5ee31ddad4490892fcefeca55359447dad2389fb7123bb6b95f42d287f1dd29c50a4ccdd0244338d862e
7
+ data.tar.gz: 0a4c863c752858ee96975d0278220ca914ba1ea5e02bddd57ab8c798b23c775c2914e81a67482c3bfa5b54af64e0f55946e99af0c2d0fef2b7470c3aec379c86
data/.rubocop.yml CHANGED
@@ -1,41 +1,19 @@
1
- Gemspec/RequiredRubyVersion:
2
- Enabled: false
3
- Layout/EndOfLine:
4
- Description: Don't enforce CRLF on Windows.
5
- Enabled: false
6
- Metrics/LineLength:
7
- Description: People have wide screens, use them.
8
- Max: 200
9
- Metrics/BlockLength:
10
- Enabled: false
11
- Metrics/MethodLength:
12
- Enabled: false
13
- Metrics/ClassLength:
14
- Enabled: false
15
- Metrics/PerceivedComplexity:
16
- Enabled: false
17
- Metrics/CyclomaticComplexity:
18
- Enabled: false
19
- Metrics/AbcSize:
20
- Enabled: false
1
+ inherit_from: .rubocop_todo.yml
21
2
 
22
- # requires 2.3's squiggly HEREDOC support, which we can't use, yet
23
- # see http://www.virtuouscode.com/2016/01/06/about-the-ruby-squiggly-heredoc-syntax/
24
- Layout/HeredocIndentation:
25
- Enabled: false
26
- # Need to ignore rubocop complaining about the name of the library.
27
- Naming/FileName:
3
+ require:
4
+ - rubocop-performance
5
+ - rubocop-rspec
6
+
7
+ AllCops:
28
8
  Exclude:
29
- - lib/ruby-pwsh.rb
30
- Style/RescueStandardError:
31
- Enabled: false
32
- Style/ExpandPathArguments:
33
- Enabled: false
34
- Style/Documentation:
35
- Enabled: false
9
+ - Gemfile
10
+ - Rakefile
11
+ - spec/fixtures/**/*
12
+ - vendor/bundle/**/*
13
+ NewCops: enable
14
+ SuggestExtensions: false
15
+ TargetRubyVersion: '2.7'
16
+
17
+ # Disabled
36
18
  Style/ClassAndModuleChildren:
37
- Exclude:
38
- - lib/puppet/provider/dsc_base_provider/dsc_base_provider.rb
39
- Style/ClassVars:
40
- Exclude:
41
- - lib/puppet/provider/dsc_base_provider/dsc_base_provider.rb
19
+ Enabled: false
data/README.md CHANGED
@@ -74,47 +74,51 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
74
74
 
75
75
  Steps to release an update to the gem and module include:
76
76
 
77
- 1. Ensure that the release branch is up to date with the main:
77
+ 1. From main, checkout a new working branch for the release prep (where xyz is the appropriate version, sans periods):
78
78
  ```bash
79
- git push upstream upstream/main:release --force
79
+ git checkout -b maint-release_prep_xyz
80
80
  ```
81
- 1. Checkout a new working branch for the release prep (where xyz is the appropriate version, sans periods):
82
- ```bash
83
- git checkout -b maint/release/prep-xyz upstream/release
84
- ```
85
- 1. Update the version in `lib/pwsh/version.rb` and `metadata.json` to the appropriate version for the new release.
86
- 1. Run the changelog update task (make sure to verify the changelog, correctly tagging PRs as needed):
81
+
82
+ 2. Update the version in `lib/pwsh/version.rb` and `metadata.json` to the appropriate version for the new release.
83
+
84
+ 3. Run the changelog update task (make sure to verify the changelog, correctly tagging PRs as needed):
87
85
  ```bash
88
86
  bundle exec rake changelog
89
87
  ```
90
- 1. Commit your changes with a short, sensible commit message, like:
91
- ```text
88
+
89
+ 4. Commit your changes with a short, sensible commit message, like:
90
+ ```bash
92
91
  git add lib/pwsh/version.rb
93
92
  git add metadata.json
94
93
  git add CHANGELOG.md
95
94
  git commit -m '(MAINT) Prep for x.y.z release'
96
95
  ```
97
- 1. Push your changes and submit a pull request for review _against the **release** branch_:
98
- ```bash
99
- git push -u origin maint/release/prep-xyz
100
- ```
101
- 1. Ensure tests pass and the code is merged to `release`.
102
- 1. Grab the commit hash from the merge commit on release, use that as the tag for the version (replacing `x.y.z` with the appropriate version and `commithash` with the relevant one), then push the tags to upstream:
96
+
97
+ 5. Push your changes and submit a pull request for review _against main:
103
98
  ```bash
104
- bundle exec rake tag['x.y.z', 'commithash']
99
+ git push -u origin maint_release_prep_xyz
105
100
  ```
106
- 1. Build the Ruby gem and publish:
101
+
102
+ 6. Ensure tests pass and the code is merged to `main`.
103
+
104
+ 7. Once the release_prep PR has been merged, checkout main and pull down the latests changes.
107
105
  ```bash
108
- bundle exec rake build
109
- bundle exec rake push['ruby-pwsh-x.y.z.gem']
106
+ git checkout main
107
+ git pull
110
108
  ```
111
- 1. Verify that the correct version now exists on [RubyGems](https://rubygems.org/search?query=ruby-pwsh)
112
- 1. Build the Puppet module:
109
+
110
+ 8. Assuming that the release_prep merge commit is at the HEAD of main we can simply create and push a tag as follows (replacing xyz with the appropriate version).
113
111
  ```bash
114
- bundle exec rake build_module
112
+ git tag -a xyx -m "Release xyz"
113
+ git push --follow-tags
115
114
  ```
116
- 1. Publish the updated module version (found in the `pkg` folder) to [the Forge](https://forge.puppet.com/puppetlabs/pwshlib).
117
- 1. Submit the [mergeback PR from the release branch to main](https://github.com/puppetlabs/ruby-pwsh/compare/main...release).
115
+
116
+ 9. Execute the publish workflow. This will:
117
+ - Create a GitHub release
118
+ - Build and publish the Gem
119
+ - Build and publish the Puppet module
120
+
121
+ 10. Finally check that the expected versions are present on rubygems.org and the Forge.
118
122
 
119
123
  ## Known Issues
120
124
 
@@ -79,13 +79,16 @@ class Puppet::Provider::DscBaseProvider
79
79
  end
80
80
  downcased_result = recursively_downcase(canonicalized)
81
81
  downcased_resource = recursively_downcase(r)
82
+ # Ensure that metaparameters are preserved when we canonicalize the resource.
83
+ metaparams = downcased_resource.select { |key, _value| Puppet::Type.metaparam?(key) }
84
+ canonicalized.merge!(metaparams) unless metaparams.nil?
82
85
  downcased_result.each do |key, value|
83
86
  # Canonicalize to the manifest value unless the downcased strings match and the attribute is not an enum:
84
87
  # - When the values don't match at all, the manifest value is desired;
85
88
  # - When the values match case insensitively but the attribute is an enum, prefer the casing of the manifest enum.
86
89
  # - When the values match case insensitively and the attribute is not an enum, prefer the casing from invoke_get_method
87
90
  canonicalized[key] = r[key] unless same?(value, downcased_resource[key]) && !enum_attributes(context).include?(key)
88
- canonicalized.delete(key) unless downcased_resource.keys.include?(key)
91
+ canonicalized.delete(key) unless downcased_resource.key?(key)
89
92
  end
90
93
  # Cache the actually canonicalized resource separately
91
94
  @@cached_canonicalized_resource << canonicalized.dup
@@ -131,7 +134,7 @@ class Puppet::Provider::DscBaseProvider
131
134
  (mandatory_get_attributes(context) - namevar_attributes(context)).include?(attribute)
132
135
  end
133
136
  # If dsc_psdscrunascredential was specified, re-add it here.
134
- mandatory_properties[:dsc_psdscrunascredential] = canonicalized_resource[:dsc_psdscrunascredential] if canonicalized_resource.keys.include?(:dsc_psdscrunascredential)
137
+ mandatory_properties[:dsc_psdscrunascredential] = canonicalized_resource[:dsc_psdscrunascredential] if canonicalized_resource.key?(:dsc_psdscrunascredential)
135
138
  end
136
139
  names.collect do |name|
137
140
  name = { name: name } if name.is_a? String
@@ -250,7 +253,7 @@ class Puppet::Provider::DscBaseProvider
250
253
 
251
254
  begin
252
255
  data = JSON.parse(output)
253
- rescue => e
256
+ rescue StandardError => e
254
257
  context.err(e)
255
258
  return nil
256
259
  end
@@ -260,7 +263,7 @@ class Puppet::Provider::DscBaseProvider
260
263
  unless error.nil? || error.empty?
261
264
  # NB: We should have a way to stop processing this resource *now* without blowing up the whole Puppet run
262
265
  # Raising an error stops processing but blows things up while context.err alerts but continues to process
263
- if error =~ /Logon failure: the user has not been granted the requested logon type at this computer/
266
+ if error.include?('Logon failure: the user has not been granted the requested logon type at this computer')
264
267
  logon_error = "PSDscRunAsCredential account specified (#{name_hash[:dsc_psdscrunascredential]['user']}) does not have appropriate logon rights; are they an administrator?"
265
268
  name_hash[:name].nil? ? context.err(logon_error) : context.err(name_hash[:name], logon_error)
266
269
  @@logon_failures << name_hash[:dsc_psdscrunascredential].dup
@@ -340,19 +343,19 @@ class Puppet::Provider::DscBaseProvider
340
343
  end
341
344
  # PowerShell does not distinguish between a return of empty array/string
342
345
  # and null but Puppet does; revert to those values if specified.
343
- data[type_key] = [] if data[type_key].nil? && query_props.keys.include?(type_key) && query_props[type_key].is_a?(Array)
346
+ data[type_key] = [] if data[type_key].nil? && query_props.key?(type_key) && query_props[type_key].is_a?(Array)
344
347
  end
345
348
  # If a resource is found, it's present, so refill this Puppet-only key
346
- data.merge!({ name: name_hash[:name] })
349
+ data[:name] = name_hash[:name]
347
350
 
348
351
  # Have to check for this to avoid a weird canonicalization warning
349
352
  # The Resource API calls canonicalize against the current state which
350
353
  # will lead to dsc_ensure being set to absent in the name_hash even if
351
354
  # it was set to present in the manifest
352
- name_hash_has_nil_keys = name_hash.select { |_k, v| v.nil? }.count.positive?
355
+ name_hash_has_nil_keys = name_hash.count { |_k, v| v.nil? }.positive?
353
356
  # We want to throw away all of the empty keys if and only if the manifest
354
357
  # declaration is for an absent resource and the resource is actually absent
355
- data.reject! { |_k, v| v.nil? } if data[:dsc_ensure] == 'Absent' && name_hash[:dsc_ensure] == 'Absent' && !name_hash_has_nil_keys
358
+ data.compact! if data[:dsc_ensure] == 'Absent' && name_hash[:dsc_ensure] == 'Absent' && !name_hash_has_nil_keys
356
359
 
357
360
  # Sort the return for order-insensitive nested enumerable comparison:
358
361
  data = recursively_sort(data)
@@ -448,7 +451,7 @@ class Puppet::Provider::DscBaseProvider
448
451
  # path to allow multiple modules to with shared dsc_resources to be installed side by side
449
452
  # The old vendored_modules_path: puppet_x/dsc_resources
450
453
  # The new vendored_modules_path: puppet_x/<module_name>/dsc_resources
451
- root_module_path = load_path.select { |path| path.match?(%r{#{puppetize_name(module_name)}/lib}) }.first
454
+ root_module_path = load_path.find { |path| path.match?(%r{#{puppetize_name(module_name)}/lib}) }
452
455
  vendored_path = if root_module_path.nil?
453
456
  File.expand_path(Pathname.new(__FILE__).dirname + '../../../' + "puppet_x/#{puppetize_name(module_name)}/dsc_resources") # rubocop:disable Style/StringConcatenation
454
457
  else
@@ -498,7 +501,7 @@ class Puppet::Provider::DscBaseProvider
498
501
  # @return [String] a uuid with underscores instead of dashes.
499
502
  def random_variable_name
500
503
  # PowerShell variables can't include dashes
501
- SecureRandom.uuid.gsub('-', '_')
504
+ SecureRandom.uuid.tr('-', '_')
502
505
  end
503
506
 
504
507
  # Return a Hash containing all of the variables defined for instantiation as well as the Ruby hash for their
@@ -637,7 +640,7 @@ class Puppet::Provider::DscBaseProvider
637
640
  # @param context [Object] the Puppet runtime context to operate in and send feedback to
638
641
  # @return [Array] returns an array of attribute names as symbols which are enums
639
642
  def enum_attributes(context)
640
- context.type.attributes.select { |_name, properties| properties[:type].match(/Enum\[/) }.keys
643
+ context.type.attributes.select { |_name, properties| properties[:type].include?('Enum[') }.keys
641
644
  end
642
645
 
643
646
  # Look through a fully formatted string, replacing all instances where a value matches the formatted properties
@@ -667,7 +670,7 @@ class Puppet::Provider::DscBaseProvider
667
670
  def munge_psmodulepath(resource)
668
671
  return unless resource[:dscmeta_resource_implementation] == 'Class'
669
672
 
670
- vendor_path = resource[:vendored_modules_path].gsub('/', '\\')
673
+ vendor_path = resource[:vendored_modules_path].tr('/', '\\')
671
674
  <<~MUNGE_PSMODULEPATH.strip
672
675
  $UnmungedPSModulePath = [System.Environment]::GetEnvironmentVariable('PSModulePath','machine')
673
676
  $MungedPSModulePath = $env:PSModulePath + ';#{vendor_path}'
@@ -728,7 +731,7 @@ class Puppet::Provider::DscBaseProvider
728
731
  # name = property_name.to_s.gsub(/^dsc_/, '').to_sym
729
732
  # Process nested CIM instances first as those neeed to be passed to higher-order
730
733
  # instances and must therefore be declared before they must be referenced
731
- cim_instance_hashes = nested_cim_instances(property_hash[:value]).flatten.reject(&:nil?)
734
+ cim_instance_hashes = nested_cim_instances(property_hash[:value]).flatten.compact
732
735
  # Sometimes the instances are an empty array
733
736
  unless cim_instance_hashes.count.zero?
734
737
  cim_instance_hashes.each do |instance|
@@ -740,7 +743,7 @@ class Puppet::Provider::DscBaseProvider
740
743
  end
741
744
  end
742
745
  # We have to handle arrays of CIM instances slightly differently
743
- if property_hash[:mof_type] =~ /\[\]$/
746
+ if /\[\]$/.match?(property_hash[:mof_type])
744
747
  class_name = property_hash[:mof_type].gsub('[]', '')
745
748
  property_hash[:value].each do |hash|
746
749
  variable_name = random_variable_name
@@ -844,7 +847,7 @@ class Puppet::Provider::DscBaseProvider
844
847
  params_block = params_block.gsub("#{param_block_name} = @()", "#{param_block_name} = [#{properties[:mof_type]}]@()")
845
848
  end
846
849
  # HACK: make CIM instances work:
847
- resource[:parameters].select { |_key, hash| hash[:mof_is_embedded] && hash[:mof_type] =~ /\[\]/ }.each do |_property_name, property_hash|
850
+ resource[:parameters].select { |_key, hash| hash[:mof_is_embedded] && hash[:mof_type].include?('[]') }.each do |_property_name, property_hash|
848
851
  formatted_property_hash = interpolate_variables(format(property_hash[:value]))
849
852
  params_block = params_block.gsub(formatted_property_hash, "[CimInstance[]]#{formatted_property_hash}")
850
853
  end
@@ -858,7 +861,7 @@ class Puppet::Provider::DscBaseProvider
858
861
  # @param resource [Hash] a hash with the information needed to run `Invoke-DscResource`
859
862
  # @return [String] A string representing the PowerShell script which will invoke the DSC Resource.
860
863
  def ps_script_content(resource)
861
- template_path = File.expand_path('../', __FILE__)
864
+ template_path = File.expand_path(__dir__)
862
865
  # Defines the helper functions
863
866
  functions = File.new("#{template_path}/invoke_dsc_resource_functions.ps1").read
864
867
  # Defines the response hash and the runtime settings
@@ -885,7 +888,7 @@ class Puppet::Provider::DscBaseProvider
885
888
  def format(value)
886
889
  Pwsh::Util.format_powershell_value(value)
887
890
  rescue RuntimeError => e
888
- raise unless e.message =~ /Sensitive \[value redacted\]/
891
+ raise unless e.message.include?('Sensitive [value redacted]')
889
892
 
890
893
  Pwsh::Util.format_powershell_value(unwrap(value))
891
894
  end
@@ -945,12 +948,12 @@ class Puppet::Provider::DscBaseProvider
945
948
  def handle_secrets(text, replacement, error_message)
946
949
  # Every secret unwrapped in this module will unwrap as "'secret#{SECRET_POSTFIX}'"
947
950
  # Currently, no known resources specify a SecureString instead of a PSCredential object.
948
- return text unless text.match(/#{Regexp.quote(SECRET_POSTFIX)}/)
951
+ return text unless /#{Regexp.quote(SECRET_POSTFIX)}/.match?(text)
949
952
 
950
953
  # In order to reduce time-to-parse, look at each line individually and *only* attempt
951
954
  # to substitute if a naive match for the secret postfix is found on the line.
952
955
  modified_text = text.split("\n").map do |line|
953
- if line.match(/#{Regexp.quote(SECRET_POSTFIX)}/)
956
+ if /#{Regexp.quote(SECRET_POSTFIX)}/.match?(line)
954
957
  line.gsub(SECRET_DATA_REGEX, replacement)
955
958
  else
956
959
  line
@@ -960,7 +963,7 @@ class Puppet::Provider::DscBaseProvider
960
963
  modified_text = modified_text.join("\n")
961
964
 
962
965
  # Something has gone wrong, error loudly
963
- raise error_message if modified_text =~ /#{Regexp.quote(SECRET_POSTFIX)}/
966
+ raise error_message if /#{Regexp.quote(SECRET_POSTFIX)}/.match?(modified_text)
964
967
 
965
968
  modified_text
966
969
  end
data/lib/pwsh/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Pwsh
4
4
  # The version of the ruby-pwsh gem
5
- VERSION = '0.10.2'
5
+ VERSION = '0.11.0.rc.1'
6
6
  end
@@ -82,7 +82,7 @@ if Pwsh::Util.on_windows?
82
82
  HKLM.open(PS_ONE_REG_PATH, ACCESS_TYPE) do |reg|
83
83
  version = reg[REG_KEY]
84
84
  end
85
- rescue
85
+ rescue StandardError
86
86
  version = nil
87
87
  end
88
88
  version
@@ -98,7 +98,7 @@ if Pwsh::Util.on_windows?
98
98
  HKLM.open(PS_THREE_REG_PATH, ACCESS_TYPE) do |reg|
99
99
  version = reg[REG_KEY]
100
100
  end
101
- rescue
101
+ rescue StandardError
102
102
  version = nil
103
103
  end
104
104
  version
data/lib/pwsh.rb CHANGED
@@ -55,7 +55,7 @@ module Pwsh
55
55
  # ignore any errors trying to tear down this unusable instance
56
56
  begin
57
57
  manager.exit unless manager.nil? # rubocop:disable Style/SafeNavigation
58
- rescue
58
+ rescue StandardError
59
59
  nil
60
60
  end
61
61
  @@instances[key] = Manager.new(cmd, args, options)
@@ -151,7 +151,7 @@ module Pwsh
151
151
  UNIXSocket.new(pipe_path)
152
152
  end
153
153
  break
154
- rescue
154
+ rescue StandardError
155
155
  sleep sleep_interval
156
156
  end
157
157
  end
@@ -208,7 +208,6 @@ module Pwsh
208
208
  out[:stderr] = out[:stderr].nil? ? [] : [out[:stderr]]
209
209
  out[:stderr] += err unless err.nil?
210
210
  out[:native_stdout] = native_stdout
211
-
212
211
  out
213
212
  end
214
213
 
@@ -224,7 +223,7 @@ module Pwsh
224
223
  # rather than expecting the pipe.close to terminate it
225
224
  begin
226
225
  write_pipe(pipe_command(:exit)) unless @pipe.closed?
227
- rescue
226
+ rescue StandardError
228
227
  nil
229
228
  end
230
229
 
@@ -245,8 +244,8 @@ module Pwsh
245
244
  # @return [String] full path to the bootstrap template
246
245
  def self.template_path
247
246
  # A PowerShell -File compatible path to bootstrap the instance
248
- path = File.expand_path('../templates', __FILE__)
249
- path = File.join(path, 'init.ps1').gsub('/', '\\')
247
+ path = File.expand_path('templates', __dir__)
248
+ path = File.join(path, 'init.ps1').tr('/', '\\')
250
249
  "\"#{path}\""
251
250
  end
252
251
 
@@ -268,7 +267,7 @@ module Pwsh
268
267
 
269
268
  # Lower bound protection. The polling resolution is only 50ms.
270
269
  timeout_ms = 50 if timeout_ms < 50
271
- rescue
270
+ rescue StandardError
272
271
  timeout_ms = 300 * 1000
273
272
  end
274
273
 
@@ -308,17 +307,17 @@ module Pwsh
308
307
 
309
308
  # PS Side expects Invoke-PowerShellUserCode is always the return value here
310
309
  # TODO: Refactor to use <<~ as soon as we can :sob:
311
- <<-CODE
312
- $params = @{
313
- Code = @'
314
- #{powershell_code}
315
- '@
316
- TimeoutMilliseconds = #{timeout_ms}
317
- WorkingDirectory = "#{working_dir}"
318
- AdditionalEnvironmentVariables = #{additional_environment_variables}
319
- }
320
-
321
- Invoke-PowerShellUserCode @params
310
+ <<~CODE
311
+ $params = @{
312
+ Code = @'
313
+ #{powershell_code}
314
+ '@
315
+ TimeoutMilliseconds = #{timeout_ms}
316
+ WorkingDirectory = "#{working_dir}"
317
+ AdditionalEnvironmentVariables = #{additional_environment_variables}
318
+ }
319
+
320
+ Invoke-PowerShellUserCode @params
322
321
  CODE
323
322
  end
324
323
 
@@ -336,10 +335,10 @@ Invoke-PowerShellUserCode @params
336
335
  #
337
336
  # @return [String] the absolute path to the PowerShell executable. Returns 'powershell.exe' if no more specific path found.
338
337
  def self.powershell_path
339
- if File.exist?("#{ENV['SYSTEMROOT']}\\sysnative\\WindowsPowershell\\v1.0\\powershell.exe")
340
- "#{ENV['SYSTEMROOT']}\\sysnative\\WindowsPowershell\\v1.0\\powershell.exe"
341
- elsif File.exist?("#{ENV['SYSTEMROOT']}\\system32\\WindowsPowershell\\v1.0\\powershell.exe")
342
- "#{ENV['SYSTEMROOT']}\\system32\\WindowsPowershell\\v1.0\\powershell.exe"
338
+ if File.exist?("#{ENV.fetch('SYSTEMROOT', nil)}\\sysnative\\WindowsPowershell\\v1.0\\powershell.exe")
339
+ "#{ENV.fetch('SYSTEMROOT', nil)}\\sysnative\\WindowsPowershell\\v1.0\\powershell.exe"
340
+ elsif File.exist?("#{ENV.fetch('SYSTEMROOT', nil)}\\system32\\WindowsPowershell\\v1.0\\powershell.exe")
341
+ "#{ENV.fetch('SYSTEMROOT', nil)}\\system32\\WindowsPowershell\\v1.0\\powershell.exe"
343
342
  else
344
343
  'powershell.exe'
345
344
  end
@@ -353,7 +352,7 @@ Invoke-PowerShellUserCode @params
353
352
  # Convert all the key names to upcase so we can be sure to find PATH etc.
354
353
  # Also while ruby can have difficulty changing the case of some UTF8 characters, we're
355
354
  # only going to use plain ASCII names so this is safe.
356
- current_path = Pwsh::Util.on_windows? ? ENV.select { |k, _| k.upcase == 'PATH' }.values[0] : ENV['PATH']
355
+ current_path = Pwsh::Util.on_windows? ? ENV.select { |k, _| k.casecmp('PATH').zero? }.values[0] : ENV.fetch('PATH', nil)
357
356
  current_path = '' if current_path.nil?
358
357
 
359
358
  # Prefer any additional paths
@@ -367,10 +366,10 @@ Invoke-PowerShellUserCode @params
367
366
  # TODO: What about PS 8?
368
367
  # TODO: Need to check on French/Turkish windows if ENV['PROGRAMFILES'] parses UTF8 names correctly
369
368
  # TODO: Need to ensure ENV['PROGRAMFILES'] is case insensitive, i.e. ENV['PROGRAMFiles'] should also resolve on Windows
370
- search_paths += ";#{ENV['PROGRAMFILES']}\\PowerShell\\6" \
371
- ";#{ENV['PROGRAMFILES(X86)']}\\PowerShell\\6" \
372
- ";#{ENV['PROGRAMFILES']}\\PowerShell\\7" \
373
- ";#{ENV['PROGRAMFILES(X86)']}\\PowerShell\\7"
369
+ search_paths += ";#{ENV.fetch('PROGRAMFILES', nil)}\\PowerShell\\6" \
370
+ ";#{ENV.fetch('PROGRAMFILES(X86)', nil)}\\PowerShell\\6" \
371
+ ";#{ENV.fetch('PROGRAMFILES', nil)}\\PowerShell\\7" \
372
+ ";#{ENV.fetch('PROGRAMFILES(X86)', nil)}\\PowerShell\\7"
374
373
  end
375
374
  raise 'No paths discovered to search for Powershell!' if search_paths.split(File::PATH_SEPARATOR).empty?
376
375
 
@@ -433,7 +432,7 @@ Invoke-PowerShellUserCode @params
433
432
  # as this resolves to a HANDLE and then calls the Windows API
434
433
  !stream.stat.nil?
435
434
  # Any exceptions mean the stream is dead
436
- rescue
435
+ rescue StandardError
437
436
  false
438
437
  end
439
438
 
@@ -497,9 +496,7 @@ Invoke-PowerShellUserCode @params
497
496
  #
498
497
  # @return nil
499
498
  def write_pipe(input)
500
- # For Compat with Ruby 2.1 and lower, it's important to use syswrite and
501
- # not write - otherwise, the pipe breaks after writing 1024 bytes.
502
- written = @pipe.syswrite(input)
499
+ written = @pipe.write(input)
503
500
  @pipe.flush
504
501
 
505
502
  if written != input.length # rubocop:disable Style/GuardClause
@@ -541,7 +538,7 @@ Invoke-PowerShellUserCode @params
541
538
  read_from_pipe(pipe, 0) { |s| output << s } while self.class.readable?(pipe)
542
539
 
543
540
  # String has been binary up to this point, so force UTF-8 now
544
- output == [] ? [] : [output.join('').force_encoding(Encoding::UTF_8)]
541
+ output == [] ? [] : [output.join.force_encoding(Encoding::UTF_8)]
545
542
  end
546
543
 
547
544
  # Open threads and pipes to read stdout and stderr from the PowerShell manager,
@@ -592,8 +589,8 @@ Invoke-PowerShellUserCode @params
592
589
 
593
590
  [
594
591
  output,
595
- stdout == [] ? nil : stdout.join(''), # native stdout
596
- stderr_reader.value # native stderr
592
+ stdout == [] ? nil : stdout.join, # native stdout
593
+ stderr_reader.value # native stderr
597
594
  ]
598
595
  ensure
599
596
  # Failsafe if the prior unlock was never reached / Mutex wasn't unlocked