Вопрос
Я получаю счетчик строк кода только для одного файла в массиве типа PSCustomObject
.Отключите все записи в массиве с помощью следующего сообщения -
Get-Content: Невозможно привязать аргумент к параметру 'Path', так как он равен нулю.
В строке: 42 символа:100
... -Контент -Path $ files.UncommentedFileName) |Measure-Object-Line |Select-Objec ...
Как мне преодолеть эту ошибку и отобразить строки кода для всех файлов в массиве?
Ограничения
- Я намерен повторно использовать функцию
Remove-VBComments
для других сценариев, в которых мне приходится обрабатывать файлы VB6.Таким образом, я не могу избежать определения и использования Remove-VBComments
- Я намереваюсь иметь функцию
Remove-VBComments
принимать конвейерный ввод, так как она будет дружественной для конвейера, чтобы ее можно было использовать в сценариях, где другие командлеты могут работать после Remove-VBComments
вконвейер - Я вынужден в среде клиента использовать PowerShell версии 4.0.
Подробности следуют -
Намерение
Мой код состоит в обобщении строк кода дляФайл кода VB6, который удален из комментариев.Комментарии всегда single '
без предоставления многострочных комментариев.Следующий скрипт PowerShell - моя попытка выполнить это намерение.
Код PowerShell
$filesToStripComment = @([PSCustomObject]@{
"SourceFileName" = ".\vb6-master\ClassTemplate\ClassBuilder\App.cls";
"UncommentedFileName" = ".\vb6-master\ClassTemplate\ClassBuilder\App.cls.uncommented"
},[PSCustomObject]@{
"SourceFileName" = ".\vb6-master\ClassTemplate\ClassBuilder\Class1.cls";
"UncommentedFileName" = ".\vb6-master\ClassTemplate\ClassBuilder\Class1.cls.uncommented"
},[PSCustomObject]@{
"SourceFileName" = ".\vb6-master\ClassTemplate\ClassBuilder\IFilterReporter.cls";
"UncommentedFileName" = ".\vb6-master\ClassTemplate\ClassBuilder\IFilterReporter.cls.uncommented"
},[PSCustomObject]@{
"SourceFileName" = ".\vb6-master\ClassTemplate\ClassBuilder\ITemplateFilter.cls";
"UncommentedFileName" = ".\vb6-master\ClassTemplate\ClassBuilder\ITemplateFilter.cls.uncommented"
});
Function Remove-VBComments {
[CmdletBinding()]
Param(
[Parameter(
Mandatory = $True,
ValueFromPipelineByPropertyName=$True
)]
[String]
$SourceFileName,
[Parameter(
Mandatory = $True,
ValueFromPipelineByPropertyName=$True
)]
[String]
$UncommentedFileName
)
Process {
(Get-Content -LiteralPath $SourceFileName) `
-replace "\'.*$",$ReplaceString -notmatch "^\s*$" `
| Out-File -LiteralPath $UncommentedFileName;
$result = [PSCustomObject]@{
SourceFileName=$($SourceFileName);
UncommentedFileName=$($UncommentedFileName)
};
Write-Output $result;
}
}
$filesToStripComment | `
Remove-VBComments -PipelineVariable "files" | `
&{Process{ `
(Get-Content -Path $files.UncommentedFileName) `
| Measure-Object -Line `
| Select-Object -Property `
@{n="FileName";e={$files.UncommentedFileName}}, `
@{n="LoC";e={$_.Lines}} `
} }
Файлы cls скопированы с github проект.
Вывод вышеуказанного кода
FileName LoC
------------- -------
.\vb6-master\ClassTemplate\ClassBuilder\App.cls.uncommented 29
Get-Content : Cannot bind argument to parameter 'Path' because it is null.
At line:42 char:100
......
# The above error repeats for all other entries in the array $filesToStripComment.
Наблюдение # 1
Если я сделаю следующее небольшое изменение после звонкаКомандлет Remove-VBComments
, я получаю количество LoC для всех файлов в массиве $filesToStripComment
.
... | Remove-VBComments | Select-Object -PipelineVariable "files" | `
& { Process { (Get-Content -Path $files.UncommentedFileName) | `
Measure-Object -Line | `
Select-Object -Property @{n="FileName",e={$files.UncommentedFileName} ...
Теперь я не понимаю, почему это тонкое изменение трубопровода Select-Object
дает мне желаемый результат, но использование PipelineVariable в командлете Remove-VBComments
не дает мне результат?!
Observation # 2
Вместо передачи массива PSCustomObject
Я тем временем импровизировал код, представив новый командлет Get-ClsFilesRecursively
.Функция выглядит следующим образом -
Function Get-ClsFilesRecursively{
[CmdletBinding()]
Param(
[Parameter(
Mandatory=$True,
ValueFromPipelineByPropertyName=$True,
)]
[String]
$SourceCodePath
)
Process{
Write-Output (Get-ChildItem -Path $SourceCodePath `
-Filter "*.cls" `
-Recurse | `
Select-Object -Property `
@{n="LiteralPath";e={$_.FullName}});
}
}
Чтобы использовать эту функцию, я выполняю такой вызов
Get-ClsFilesRecursively -SourceCodePath . -PipelineVariable "files" | `
& { Process { `
Get-Content -LiteralPath $files.LiteralPath | `
Measure-Object -Line | `
Select-Object -Property @{n="File name";e={$files.LiteralPath}} `
@{n="LoC"; e={$_.Lines}}
}}
Теперь это дает мне строки кода для всех файлов вкаталог;без каких-либо исключений.Однако этот вызов включает комментарии в файлах.Теперь, если я передам Remove-VBCommments
в приведенной выше последовательности вызовов, я вернусь к проблеме, о которой упоминал выше.Я озадачен тем, что Remove-VBComments
не работает должным образом с PipelineVariable
, тогда как другие командлеты работают с PipelineVariable
!
Пожалуйста, помогите!