ruby-pwsh 0.10.2 → 0.11.0.rc.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 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