mirror of
https://github.com/github/spec-kit.git
synced 2026-07-03 12:28:06 +08:00
* fix(scripts): send check-prerequisites.ps1 errors to stderr The validation errors and run-hints in check-prerequisites.ps1 were written with Write-Output, so they went to stdout. This script is usually run with -Json and its stdout parsed by the agent, so an error (e.g. missing plan.md) leaves the parser with an error string instead of JSON. The bash counterpart already writes these to stderr (>&2), as do the sibling PowerShell scripts (setup-tasks.ps1, common.ps1's Get-FeaturePathsEnv). Switch the six error/hint lines to [Console]::Error.WriteLine so stdout stays clean and the two shells match. * test(scripts): assert check-prerequisites errors stay on stderr Per the #3122 bug assessment, tighten the failure-path tests so they verify stdout stays clean (empty / valid JSON) and the error text only appears on stderr, instead of checking the combined stdout+stderr string. Covers all three PowerShell validation paths (missing feature dir, missing plan.md, missing tasks.md with -RequireTasks) and the bash counterpart. The two new error-routing tests fail on the pre-fix script (errors on stdout) and pass after it.
148 lines
4.9 KiB
PowerShell
148 lines
4.9 KiB
PowerShell
#!/usr/bin/env pwsh
|
|
|
|
# Consolidated prerequisite checking script (PowerShell)
|
|
#
|
|
# This script provides unified prerequisite checking for Spec-Driven Development workflow.
|
|
# It replaces the functionality previously spread across multiple scripts.
|
|
#
|
|
# Usage: ./check-prerequisites.ps1 [OPTIONS]
|
|
#
|
|
# OPTIONS:
|
|
# -Json Output in JSON format
|
|
# -RequireTasks Require tasks.md to exist (for implementation phase)
|
|
# -IncludeTasks Include tasks.md in AVAILABLE_DOCS list
|
|
# -PathsOnly Only output path variables (no validation)
|
|
# -Help, -h Show help message
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[switch]$Json,
|
|
[switch]$RequireTasks,
|
|
[switch]$IncludeTasks,
|
|
[switch]$PathsOnly,
|
|
[switch]$Help
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
# Show help if requested
|
|
if ($Help) {
|
|
Write-Output @"
|
|
Usage: check-prerequisites.ps1 [OPTIONS]
|
|
|
|
Consolidated prerequisite checking for Spec-Driven Development workflow.
|
|
|
|
OPTIONS:
|
|
-Json Output in JSON format
|
|
-RequireTasks Require tasks.md to exist (for implementation phase)
|
|
-IncludeTasks Include tasks.md in AVAILABLE_DOCS list
|
|
-PathsOnly Only output path variables (no prerequisite validation)
|
|
-Help, -h Show this help message
|
|
|
|
EXAMPLES:
|
|
# Check task prerequisites (plan.md required)
|
|
.\check-prerequisites.ps1 -Json
|
|
|
|
# Check implementation prerequisites (plan.md + tasks.md required)
|
|
.\check-prerequisites.ps1 -Json -RequireTasks -IncludeTasks
|
|
|
|
# Get feature paths only (no validation)
|
|
.\check-prerequisites.ps1 -PathsOnly
|
|
|
|
"@
|
|
exit 0
|
|
}
|
|
|
|
# Source common functions
|
|
. "$PSScriptRoot/common.ps1"
|
|
|
|
# Get feature paths
|
|
$paths = Get-FeaturePathsEnv
|
|
|
|
# If paths-only mode, output paths and exit (no validation)
|
|
if ($PathsOnly) {
|
|
if ($Json) {
|
|
[PSCustomObject]@{
|
|
REPO_ROOT = $paths.REPO_ROOT
|
|
BRANCH = $paths.CURRENT_BRANCH
|
|
FEATURE_DIR = $paths.FEATURE_DIR
|
|
FEATURE_SPEC = $paths.FEATURE_SPEC
|
|
IMPL_PLAN = $paths.IMPL_PLAN
|
|
TASKS = $paths.TASKS
|
|
} | ConvertTo-Json -Compress
|
|
} else {
|
|
Write-Output "REPO_ROOT: $($paths.REPO_ROOT)"
|
|
Write-Output "BRANCH: $($paths.CURRENT_BRANCH)"
|
|
Write-Output "FEATURE_DIR: $($paths.FEATURE_DIR)"
|
|
Write-Output "FEATURE_SPEC: $($paths.FEATURE_SPEC)"
|
|
Write-Output "IMPL_PLAN: $($paths.IMPL_PLAN)"
|
|
Write-Output "TASKS: $($paths.TASKS)"
|
|
}
|
|
exit 0
|
|
}
|
|
|
|
# Validate required directories and files
|
|
if (-not (Test-Path $paths.FEATURE_DIR -PathType Container)) {
|
|
[Console]::Error.WriteLine("ERROR: Feature directory not found: $($paths.FEATURE_DIR)")
|
|
$specifyCommand = Format-SpecKitCommand -CommandName 'specify' -RepoRoot $paths.REPO_ROOT
|
|
[Console]::Error.WriteLine("Run $specifyCommand first to create the feature structure.")
|
|
exit 1
|
|
}
|
|
|
|
if (-not (Test-Path $paths.IMPL_PLAN -PathType Leaf)) {
|
|
[Console]::Error.WriteLine("ERROR: plan.md not found in $($paths.FEATURE_DIR)")
|
|
$planCommand = Format-SpecKitCommand -CommandName 'plan' -RepoRoot $paths.REPO_ROOT
|
|
[Console]::Error.WriteLine("Run $planCommand first to create the implementation plan.")
|
|
exit 1
|
|
}
|
|
|
|
# Check for tasks.md if required
|
|
if ($RequireTasks -and -not (Test-Path $paths.TASKS -PathType Leaf)) {
|
|
[Console]::Error.WriteLine("ERROR: tasks.md not found in $($paths.FEATURE_DIR)")
|
|
$tasksCommand = Format-SpecKitCommand -CommandName 'tasks' -RepoRoot $paths.REPO_ROOT
|
|
[Console]::Error.WriteLine("Run $tasksCommand first to create the task list.")
|
|
exit 1
|
|
}
|
|
|
|
# Build list of available documents
|
|
$docs = @()
|
|
|
|
# Always check these optional docs
|
|
if (Test-Path $paths.RESEARCH) { $docs += 'research.md' }
|
|
if (Test-Path $paths.DATA_MODEL) { $docs += 'data-model.md' }
|
|
|
|
# Check contracts directory (only if it exists and has files)
|
|
if ((Test-Path $paths.CONTRACTS_DIR) -and (Get-ChildItem -Path $paths.CONTRACTS_DIR -ErrorAction SilentlyContinue | Select-Object -First 1)) {
|
|
$docs += 'contracts/'
|
|
}
|
|
|
|
if (Test-Path $paths.QUICKSTART) { $docs += 'quickstart.md' }
|
|
|
|
# Include tasks.md if requested and it exists
|
|
if ($IncludeTasks -and (Test-Path $paths.TASKS)) {
|
|
$docs += 'tasks.md'
|
|
}
|
|
|
|
# Output results
|
|
if ($Json) {
|
|
# JSON output
|
|
[PSCustomObject]@{
|
|
FEATURE_DIR = $paths.FEATURE_DIR
|
|
AVAILABLE_DOCS = $docs
|
|
} | ConvertTo-Json -Compress
|
|
} else {
|
|
# Text output
|
|
Write-Output "FEATURE_DIR:$($paths.FEATURE_DIR)"
|
|
Write-Output "AVAILABLE_DOCS:"
|
|
|
|
# Show status of each potential document
|
|
Test-FileExists -Path $paths.RESEARCH -Description 'research.md' | Out-Null
|
|
Test-FileExists -Path $paths.DATA_MODEL -Description 'data-model.md' | Out-Null
|
|
Test-DirHasFiles -Path $paths.CONTRACTS_DIR -Description 'contracts/' | Out-Null
|
|
Test-FileExists -Path $paths.QUICKSTART -Description 'quickstart.md' | Out-Null
|
|
|
|
if ($IncludeTasks) {
|
|
Test-FileExists -Path $paths.TASKS -Description 'tasks.md' | Out-Null
|
|
}
|
|
}
|