From b00c7fb0f37f5b5ab209c9534fe4ca80ddbb8d7f Mon Sep 17 00:00:00 2001 From: Yury Bushmelev Date: Mon, 11 May 2026 11:00:06 +0800 Subject: [PATCH 1/4] feat!: remove puppet_x/pty.rb file This file might confuse any future module under PTY namespace. --- lib/puppet_x/pty.rb | 4 ---- lib/puppet_x/pty/io.rb | 6 +++++- 2 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 lib/puppet_x/pty.rb diff --git a/lib/puppet_x/pty.rb b/lib/puppet_x/pty.rb deleted file mode 100644 index e97ed36..0000000 --- a/lib/puppet_x/pty.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'puppet_x' - -# Define PuppetX::PTY namespace -module PuppetX::PTY; end diff --git a/lib/puppet_x/pty/io.rb b/lib/puppet_x/pty/io.rb index 0296ada..ef15a50 100644 --- a/lib/puppet_x/pty/io.rb +++ b/lib/puppet_x/pty/io.rb @@ -1,10 +1,14 @@ # frozen_string_literal: true -require 'puppet_x/pty' require 'io/console' require 'io/wait' require 'expect' +# Defined PuppetX namespace +module PuppetX; end +# Defined PuppetX::PTY namespace +module PuppetX::PTY; end + # Wrapper class for the pty interaction # @method write Write a string as is # @method puts Write a string with line feed appended From a043f51d0003d194134536ce1a4692d37a6fc800 Mon Sep 17 00:00:00 2001 From: Yury Bushmelev Date: Mon, 11 May 2026 11:16:13 +0800 Subject: [PATCH 2/4] test: add non-block pty::spawn() unit test --- spec/functions/pty/spawn_spec.rb | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 spec/functions/pty/spawn_spec.rb diff --git a/spec/functions/pty/spawn_spec.rb b/spec/functions/pty/spawn_spec.rb new file mode 100644 index 0000000..54a2d92 --- /dev/null +++ b/spec/functions/pty/spawn_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'bolt_spec/bolt_context' +require 'pty' +require_relative '../../../lib/puppet_x/pty/io' + +describe 'pty::spawn' do + let(:pty_io) { PuppetX::PTY::IO.new } + let(:command) { ['/nonexistent', '1', '2', '3'] } + let(:input) { instance_double(StringIO) } + let(:output) { instance_double(StringIO) } + let(:pid) { 123_456 } + + include BoltSpec::BoltContext + # This function should always be tested in the Bolt context + around(:each) do |example| + in_bolt_context do + example.run + end + end + + context 'in non-block form' do + it 'runs successfully' do + expect(PuppetX::PTY::IO).to receive(:new).and_return(pty_io) + expect(PTY).to receive(:spawn).with(*command).and_return([input, output, pid]) + is_expected.to run.with_params(command).and_return(pty_io) + end + end +end From 107bff7da036986fa8cdb07529646c20f33bb8df Mon Sep 17 00:00:00 2001 From: Yury Bushmelev Date: Tue, 9 Jun 2026 17:19:05 +0800 Subject: [PATCH 3/4] feat!: spawn() block form returns block result now --- lib/puppet/functions/pty/spawn.rb | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/puppet/functions/pty/spawn.rb b/lib/puppet/functions/pty/spawn.rb index 991d9e0..1ea33a1 100644 --- a/lib/puppet/functions/pty/spawn.rb +++ b/lib/puppet/functions/pty/spawn.rb @@ -18,7 +18,9 @@ # The command to spawn. # @param block # The code block, that is using PTY::IO object yielded to talk to the - # command executed. + # command executed. The process executed will be SIGTERM-ed and waited on + # block exit. + # @return Block result. # # @example Spawn /bin/sh and get the hostname # pty::spawn(['/bin/sh', '--norc']) |$pty| { @@ -31,14 +33,14 @@ dispatch :spawn_with_block do param 'Array[String[1]]', :cmd block_param 'Callable[PTY::IO]', :block - return_type 'Undef' + return_type 'Any' end # Spawns the specified command on a newly allocated pty (non-block form). # # @param cmd # The command to spawn. - # @return The PTY::IO object + # @return The PTY::IO object. # # @example Spawn /bin/sh and get the hostname # $pty = pty::spawn(['/bin/sh', '--norc']) @@ -56,12 +58,10 @@ def spawn_with_block(cmd) fail_if_not_in_plan - PTY.spawn(*cmd) do |input, output, pid| - pty_io = PuppetX::PTY::IO.new - pty_io.private_init(input, output, pid) - yield pty_io - end - nil + pty_io = spawn(cmd) + yield pty_io + ensure + pty_io&.close end def spawn(cmd) From b406465b721ec93e6e3c2adfeedee2b4e199db61 Mon Sep 17 00:00:00 2001 From: Yury Bushmelev Date: Tue, 9 Jun 2026 17:25:54 +0800 Subject: [PATCH 4/4] fix: wait for possible input longer in type_in() --- lib/puppet_x/pty/io.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/puppet_x/pty/io.rb b/lib/puppet_x/pty/io.rb index ef15a50..f1a7073 100644 --- a/lib/puppet_x/pty/io.rb +++ b/lib/puppet_x/pty/io.rb @@ -158,7 +158,7 @@ def type_in(msg, opts = {}) msg.chars.each do |c| @output.putc c loop do - return nil unless @input.wait_readable(1) # Return Undef if timeout expired and no input here + return nil unless @input.wait_readable(30) # Return Undef if timeout expired and no input here i = @input.getc break if i == c end