8000 Add `Write-*` proxy for each `Format-*` cmdlet · Issue #20001 · PowerShell/PowerShell · GitHub
[go: up one dir, main page]

Skip to content

Add Write-* proxy for each Format-* cmdlet #20001

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
iRon7 opened this issue Jul 20, 2023 · 4 comments
Closed

Add Write-* proxy for each Format-* cmdlet #20001

iRon7 opened this issue Jul 20, 2023 · 4 comments
Labels
Issue-Enhancement the issue is more of a feature request than a bug WG-Engine core PowerShell engine, interpreter, and runtime

Comments

@iRon7
Copy link
iRon7 commented Jul 20, 2023

Summary of the new feature / enhancement

To avoid avoid wrapping cmdlet pipelines and better support a single pipeline, it would helpful to tee formatted data directly to the host and continue with the input objects.
This further ties into the Feature Request / Idea: #19989 -PassThru as common parameter followed up by #20133 A common -Reprocess parameter for passing through the current input item

Proposed technical implementation details (optional)

For each Format-*:

  • Format-Custom
  • Format-List
  • Format-Wide
  • Format-Hex
  • Format-Table

There could an Write-* cmdlet:

  • Write-Custom
  • Write-List
  • Write-Wide
  • Write-Hex
  • Write-Table

Which might be a simply proxy command which an additional -PassThru parameter.

As questioned here: Powershell pipeline both remove-item and call function
This will allow for pipelines like (wishful thinking):

Get-ChildItem .\ -Include *.jpg | Write-Table -PassThru | Remove-Item $_.fullname -Force -Recurse

Caveat:

  • There is no paging possible these purposed proxy cmdlets
@iRon7 iRon7 added Issue-Enhancement the issue is more of a feature request than a bug Needs-Triage The issue is new and needs to be triaged by a work group. labels Jul 20, 2023
@iRon7 iRon7 changed the title Add Out-* proxy for each Format-* cmdlet Add Write-* proxy for each Format-* cmdlet Jul 20, 2023
@iRon7
Copy link
Author
iRon7 commented Jul 20, 2023
Write-* prototype generator
'Custom', 'List', 'Wide', 'Hex', 'Table' | Foreach-Object {
  $FormatCommand = Get-Command Format-$_
  $MetaData = [System.Management.Automation.CommandMetadata]$FormatCommand
  $ProxyCommand = [System.Management.Automation.ProxyCommand]::Create($MetaData)
  $AST = [System.Management.Automation.Language.Parser]::ParseInput($ProxyCommand, [ref]$Null, [ref]$Null)

  $LastParam = $AST.ParamBlock.Parameters.Extent[-1]
  $BeginBlock = $AST.BeginBlock.Extent
  $ProcessBlock = $AST.ProcessBlock.Extent

  $WriteCommand = $ProxyCommand.SubString(0, $LastParam.EndOffset) + @'
,

  [switch]
  ${PassThru}
'@ + $ProxyCommand.SubString($LastParam.EndOffset, ($BeginBlock.StartOffset - $LastParam.EndOffset)) + @'
begin
{
  try {
      $outBuffer = $null
      if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
      {
          $PSBoundParameters['OutBuffer'] = 1
      }

      if ($PSBoundParameters.TryGetValue('PassThru', [ref]$outBuffer))
      {
          $Null = $PSBoundParameters.Remove('PassThru')
      }
      $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Utility\Format-
'@ + $_ + @'
', [System.Management.Automation.CommandTypes]::Cmdlet)
      $scriptCmd = { & $wrappedCmd @PSBoundParameters | Out-Host }

      $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
      $steppablePipeline.Begin($PSCmdlet)
  } catch {
      throw
  }
}
'@ + $ProxyCommand.SubString($BeginBlock.EndOffset, ($ProcessBlock.StartOffset - $BeginBlock.EndOffset)) + @'
process
{
  try {
      if ($PassThru) { $_ }
      $steppablePipeline.Process($_)
  } catch {
      throw
  }
}
'@ + $ProxyCommand.SubString($ProcessBlock.EndOffset)

  $Null = New-Item -Path Function:\ -Name Write-$_ -Value $WriteCommand -Force
}
gci *.txt | Write-List -PassThru | Get-Item # or: ... | Remove-Item

@daxian-dbw daxian-dbw added the WG-Engine core PowerShell engine, interpreter, and runtime label Jul 21, 2023
@mklement0
Copy link
Contributor
mklement0 commented Aug 16, 2023

@iRon7, wouldn't the implementation of #19827 facilitate this use case, at least with the default formatting? (And, as stated in the linked issue, instead of -Console you can already use -FilePath ($IsWindows ? '\\.\CON': '/dev/tty'))

# Print the file-info objects to the terminal while also passing them through to the pipeline.
Get-ChildItem .\ -Include *.jpg | Tee-Object -Console | Remove-Item -Force -Recurse -WhatIf

For other formatting and possibly other data processing, @dkaszews' yet-to-be-fully-fleshed-out Tee-Object -Process { ... } proposal could help:

@iRon7
Copy link
Author
iRon7 commented Aug 17, 2023

@mklement0,

wouldn't the implementation of #19827 facilitate this use case

That is correct for Write-Host (which currently only writes to the information stream/host). The differents is indeed in the "for other formatting and possibly other data processing" where @dkaszews' yet-to-be-fully-fleshed-out Tee-Object -Process { ... } proposal would involve a complete new pipeline with the overhead of all (Begin, End) processing blocks. which is IMO not always necessarily in the #20133 purpose.

@iRon7
Copy link
Author
iRon7 commented Aug 18, 2023

I have closed this purpose as it is now covered by the #20133 a common -Tee parameter purpose.
Wishful thinking:

... | Format-Table -Tee | ...

@iRon7 iRon7 closed this as completed Aug 18, 2023
@microsoft-github-policy-service microsoft-github-policy-service bot removed the Needs-Triage The issue is new and needs to be triaged by a work group. label Aug 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Enhancement the issue is more of a feature request than a bug WG-Engine core PowerShell engine, interpreter, and runtime
Projects
None yet
Development

No branches or pull requests

3 participants
0