Repository navigation
PowerShell wrapper: documented positional paths bind to -Root and silently scan "." #315
Description
Дефект
Документированный способ вызова PowerShell-обёртки принимает путь, но связывает его с -Root, после чего сканирует ..
Собственные примеры скрипта:
scripts\own-check.ps1 -Format msbuild -- src\MyApp
scripts\own-check.ps1 -Format github -Severity warning -FailOnFinding -- .Первый из них сканирует не src\MyApp. Он принимает src\MyApp за корень чекаута Own.NET и проверяет текущий каталог.
Почему так
В PowerShell -- завершает разбор параметров: всё, что после него, связывается позиционно. В блоке параметров $Root объявлен первым и занимает нулевую позицию, а $Paths задуман как ValueFromRemainingArguments. Скрипт сам себе противоречит: он даже содержит строку, отбрасывающую литерал -- из $Paths, — то есть автор ожидал, что путь туда дойдёт.
Проверено на сокращённом блоке параметров (PowerShell 7.4.6):
| Вызов | Куда попал путь |
|---|---|
-Format github -- /tmp/tree |
$Root |
-Format github /tmp/tree |
$Root |
-Format github -Paths /tmp/tree |
$Paths ✔ |
Почему это P1, а не опечатка в документации
Отказ тихий. Пользователь просит проверить каталог A, обёртка проверяет каталог B и не сообщает об ошибке. Если в текущем каталоге чисто, он получает зелёный результат и уверенность, что в A нет находок.
Это тот же класс лжи, который арки A1 и A4 методично выжигали: «не посмотрел» не имеет права выглядеть как «посмотрел и ничего не нашёл». Здесь хуже — инструмент посмотрел, но не туда, куда его просили.
На Windows с настоящим чекаутом это чаще всего проявится как жёсткая ошибка (экстрактор ищется внутри src\MyApp и не находится → exit 2), что как раз и вскрыло дефект в CI. Но при неудачном стечении — если по указанному пути окажется что-то похожее на чекаут, или при вызове из корня репозитория — тишина вероятна.
Критерии приёмки
documented `-- <path>` form → <path> binds to Paths
bare positional <path> → <path> binds to Paths, if kept supported
explicit -Paths <path> → unchanged
explicit -Root <checkout> → unchanged
no path → defaults to "."
requested target has finding,
cwd is clean → finding must still appear
Последняя строка — главная: она ловит именно тихую подмену цели, а не только жёсткий отказ.
Заметки к исправлению
- Причина — порядок позиционных параметров, поэтому чинить нужно связывание (позиция у
$Paths, снятие позиции у$Root), а не примеры в документации. Переписать примеры под текущее поведение значило бы узаконить дефект. - Закрепить проверкой в джобе
own-check-ps1-surface, добавленной в test(ci): pin own-check.ps1's exit-code tiers on Windows (#313) #314: там уже есть Windows-раннер и фикстуры чистого и «протекающего» деревьев. - Эквивалент на
own-check.shне затронут: там разбор аргументов свой и--обрабатывается явно.
Контекст
Найдено при работе над #313 — не чтением, а исполнением обёртки. Правка намеренно не включена в #314: тест, обнаруживший дефект, не должен чинить объект испытания в том же пакете.
Activity
Merge pull request #314: test(ci): pin own-check.ps1's exit-code tier…
fix(powershell): bind positional scan paths to -Paths