@kabran-tecnologia/kabran-config 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kabran-tecnologia/kabran-config",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Shared quality configurations, enforcement scripts, and CI/CD tooling for Kabran projects",
|
|
5
5
|
"author": "Kabran",
|
|
6
6
|
"license": "MIT",
|
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
"bin": {
|
|
12
12
|
"kabran-setup": "src/scripts/setup.mjs",
|
|
13
13
|
"kabran-ci": "src/scripts/ci/ci-runner.sh",
|
|
14
|
-
"kabran-pr-comment": "src/scripts/pr-quality-comment.mjs"
|
|
14
|
+
"kabran-pr-comment": "src/scripts/pr-quality-comment.mjs",
|
|
15
|
+
"kabran-traceability": "src/scripts/traceability/validate-traceability.sh",
|
|
16
|
+
"kabran-coverage": "src/scripts/traceability/coverage-report.sh"
|
|
15
17
|
},
|
|
16
18
|
"exports": {
|
|
17
19
|
"./eslint": "./src/eslint.mjs",
|
|
@@ -29,6 +31,7 @@
|
|
|
29
31
|
"./scripts/env-validator": "./src/scripts/env-validator.mjs",
|
|
30
32
|
"./scripts/ci/*": "./src/scripts/ci/*",
|
|
31
33
|
"./scripts/deploy/*": "./src/scripts/deploy/*",
|
|
34
|
+
"./scripts/traceability/*": "./src/scripts/traceability/*",
|
|
32
35
|
"./scripts/setup": "./src/scripts/setup.mjs",
|
|
33
36
|
"./scripts/quality-standard-validator": "./src/scripts/quality-standard-validator.mjs",
|
|
34
37
|
"./scripts/generate-ci-result": "./src/scripts/generate-ci-result.mjs",
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ==============================================================================
|
|
3
|
+
# Kabran Traceability Coverage Report
|
|
4
|
+
# Part of @kabran-owner/kabran-config
|
|
5
|
+
# Implements PROP-006: JSDoc Traceability Tags
|
|
6
|
+
#
|
|
7
|
+
# Generates a report of spec coverage in the codebase.
|
|
8
|
+
# Shows which specs have code implementing them and which ACs are covered.
|
|
9
|
+
# ==============================================================================
|
|
10
|
+
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
# Source core functions
|
|
14
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
15
|
+
# shellcheck source=traceability-core.sh
|
|
16
|
+
source "$SCRIPT_DIR/traceability-core.sh"
|
|
17
|
+
|
|
18
|
+
# ==============================================================================
|
|
19
|
+
# Configuration
|
|
20
|
+
# ==============================================================================
|
|
21
|
+
|
|
22
|
+
SEARCH_PATH="${1:-.}"
|
|
23
|
+
SPEC_FILTER="${2:-}"
|
|
24
|
+
OUTPUT_FORMAT="${OUTPUT_FORMAT:-text}"
|
|
25
|
+
|
|
26
|
+
# ==============================================================================
|
|
27
|
+
# Report Functions
|
|
28
|
+
# ==============================================================================
|
|
29
|
+
|
|
30
|
+
# Generate report for a specific spec
|
|
31
|
+
report_spec() {
|
|
32
|
+
local spec="$1"
|
|
33
|
+
local files
|
|
34
|
+
|
|
35
|
+
files=$(grep -rl "@spec $spec" --include="*.ts" --include="*.tsx" "$SEARCH_PATH" 2>/dev/null || true)
|
|
36
|
+
|
|
37
|
+
if [ -z "$files" ]; then
|
|
38
|
+
return
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
echo ""
|
|
42
|
+
echo "=== $spec ==="
|
|
43
|
+
echo ""
|
|
44
|
+
echo "Files:"
|
|
45
|
+
echo "$files" | while read -r file; do
|
|
46
|
+
[ -n "$file" ] && echo " - $file"
|
|
47
|
+
done
|
|
48
|
+
|
|
49
|
+
echo ""
|
|
50
|
+
echo "ACs Implemented:"
|
|
51
|
+
echo "$files" | while read -r file; do
|
|
52
|
+
[ -n "$file" ] && extract_implements "$file"
|
|
53
|
+
done | sort -u | while read -r ac; do
|
|
54
|
+
[ -n "$ac" ] && echo " - $ac"
|
|
55
|
+
done
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
# Generate summary report
|
|
59
|
+
report_summary() {
|
|
60
|
+
log_section "Traceability Coverage Report v${TRACEABILITY_VERSION}"
|
|
61
|
+
log_info "Search path: $SEARCH_PATH"
|
|
62
|
+
echo ""
|
|
63
|
+
|
|
64
|
+
local total_files
|
|
65
|
+
local tagged_files
|
|
66
|
+
local specs
|
|
67
|
+
|
|
68
|
+
total_files=$(count_total_files "$SEARCH_PATH")
|
|
69
|
+
tagged_files=$(count_tagged_files "$SEARCH_PATH")
|
|
70
|
+
|
|
71
|
+
echo "## Overview"
|
|
72
|
+
echo ""
|
|
73
|
+
echo "| Metric | Value |"
|
|
74
|
+
echo "|--------|-------|"
|
|
75
|
+
echo "| Total TypeScript files | $total_files |"
|
|
76
|
+
echo "| Files with @spec | $tagged_files |"
|
|
77
|
+
|
|
78
|
+
if [ "$total_files" -gt 0 ]; then
|
|
79
|
+
local coverage=$((tagged_files * 100 / total_files))
|
|
80
|
+
echo "| Coverage | $coverage% |"
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
echo ""
|
|
84
|
+
echo "## Specs Found"
|
|
85
|
+
echo ""
|
|
86
|
+
|
|
87
|
+
# Find all unique specs
|
|
88
|
+
specs=$(grep -roh '@spec S[0-9]*' --include="*.ts" --include="*.tsx" "$SEARCH_PATH" 2>/dev/null | sed 's/@spec //' | sort -u || true)
|
|
89
|
+
|
|
90
|
+
if [ -z "$specs" ]; then
|
|
91
|
+
echo "No @spec tags found in codebase."
|
|
92
|
+
return
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
echo "$specs" | while read -r spec; do
|
|
96
|
+
if [ -n "$spec" ]; then
|
|
97
|
+
local file_count
|
|
98
|
+
file_count=$(grep -rl "@spec $spec" --include="*.ts" --include="*.tsx" "$SEARCH_PATH" 2>/dev/null | wc -l)
|
|
99
|
+
echo "- **$spec**: $file_count files"
|
|
100
|
+
fi
|
|
101
|
+
done
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
# Generate detailed report for all specs
|
|
105
|
+
report_detailed() {
|
|
106
|
+
report_summary
|
|
107
|
+
|
|
108
|
+
echo ""
|
|
109
|
+
echo "## Detailed Coverage"
|
|
110
|
+
|
|
111
|
+
local specs
|
|
112
|
+
specs=$(grep -roh '@spec S[0-9]*' --include="*.ts" --include="*.tsx" "$SEARCH_PATH" 2>/dev/null | sed 's/@spec //' | sort -u || true)
|
|
113
|
+
|
|
114
|
+
if [ -n "$specs" ]; then
|
|
115
|
+
echo "$specs" | while read -r spec; do
|
|
116
|
+
[ -n "$spec" ] && report_spec "$spec"
|
|
117
|
+
done
|
|
118
|
+
fi
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
# Generate JSON report
|
|
122
|
+
report_json() {
|
|
123
|
+
local total_files
|
|
124
|
+
local tagged_files
|
|
125
|
+
local specs
|
|
126
|
+
|
|
127
|
+
total_files=$(count_total_files "$SEARCH_PATH")
|
|
128
|
+
tagged_files=$(count_tagged_files "$SEARCH_PATH")
|
|
129
|
+
specs=$(grep -roh '@spec S[0-9]*' --include="*.ts" --include="*.tsx" "$SEARCH_PATH" 2>/dev/null | sed 's/@spec //' | sort -u || true)
|
|
130
|
+
|
|
131
|
+
local coverage=0
|
|
132
|
+
if [ "$total_files" -gt 0 ]; then
|
|
133
|
+
coverage=$((tagged_files * 100 / total_files))
|
|
134
|
+
fi
|
|
135
|
+
|
|
136
|
+
echo "{"
|
|
137
|
+
echo " \"version\": \"${TRACEABILITY_VERSION}\","
|
|
138
|
+
echo " \"searchPath\": \"$SEARCH_PATH\","
|
|
139
|
+
echo " \"totalFiles\": $total_files,"
|
|
140
|
+
echo " \"taggedFiles\": $tagged_files,"
|
|
141
|
+
echo " \"coverage\": $coverage,"
|
|
142
|
+
echo " \"specs\": ["
|
|
143
|
+
|
|
144
|
+
local first=true
|
|
145
|
+
if [ -n "$specs" ]; then
|
|
146
|
+
echo "$specs" | while read -r spec; do
|
|
147
|
+
if [ -n "$spec" ]; then
|
|
148
|
+
local file_count
|
|
149
|
+
file_count=$(grep -rl "@spec $spec" --include="*.ts" --include="*.tsx" "$SEARCH_PATH" 2>/dev/null | wc -l)
|
|
150
|
+
if [ "$first" = true ]; then
|
|
151
|
+
first=false
|
|
152
|
+
else
|
|
153
|
+
echo ","
|
|
154
|
+
fi
|
|
155
|
+
echo -n " { \"id\": \"$spec\", \"files\": $file_count }"
|
|
156
|
+
fi
|
|
157
|
+
done
|
|
158
|
+
fi
|
|
159
|
+
|
|
160
|
+
echo ""
|
|
161
|
+
echo " ]"
|
|
162
|
+
echo "}"
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
# ==============================================================================
|
|
166
|
+
# Help
|
|
167
|
+
# ==============================================================================
|
|
168
|
+
|
|
169
|
+
show_help() {
|
|
170
|
+
cat << EOF
|
|
171
|
+
Kabran Traceability Coverage Report v${TRACEABILITY_VERSION}
|
|
172
|
+
|
|
173
|
+
Usage: coverage-report.sh [path] [spec] [options]
|
|
174
|
+
|
|
175
|
+
Arguments:
|
|
176
|
+
path Directory to scan (default: current directory)
|
|
177
|
+
spec Filter by specific spec ID (e.g., S25)
|
|
178
|
+
|
|
179
|
+
Environment Variables:
|
|
180
|
+
OUTPUT_FORMAT Output format: text, detailed, json (default: text)
|
|
181
|
+
|
|
182
|
+
Examples:
|
|
183
|
+
coverage-report.sh ./src
|
|
184
|
+
coverage-report.sh ./src S25
|
|
185
|
+
OUTPUT_FORMAT=json coverage-report.sh ./src
|
|
186
|
+
OUTPUT_FORMAT=detailed coverage-report.sh ./src
|
|
187
|
+
|
|
188
|
+
Output Formats:
|
|
189
|
+
text Summary with spec counts
|
|
190
|
+
detailed Full breakdown with files and ACs per spec
|
|
191
|
+
json Machine-readable JSON output
|
|
192
|
+
|
|
193
|
+
EOF
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
# ==============================================================================
|
|
197
|
+
# Entry Point
|
|
198
|
+
# ==============================================================================
|
|
199
|
+
|
|
200
|
+
if [[ "${1:-}" == "--help" ]] || [[ "${1:-}" == "-h" ]]; then
|
|
201
|
+
show_help
|
|
202
|
+
exit 0
|
|
203
|
+
fi
|
|
204
|
+
|
|
205
|
+
# Handle specific spec filter
|
|
206
|
+
if [ -n "$SPEC_FILTER" ]; then
|
|
207
|
+
report_spec "$SPEC_FILTER"
|
|
208
|
+
exit 0
|
|
209
|
+
fi
|
|
210
|
+
|
|
211
|
+
# Generate report based on format
|
|
212
|
+
case "$OUTPUT_FORMAT" in
|
|
213
|
+
json)
|
|
214
|
+
report_json
|
|
215
|
+
;;
|
|
216
|
+
detailed)
|
|
217
|
+
report_detailed
|
|
218
|
+
;;
|
|
219
|
+
*)
|
|
220
|
+
report_summary
|
|
221
|
+
;;
|
|
222
|
+
esac
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ==============================================================================
|
|
3
|
+
# Kabran Traceability Core - Shared Functions
|
|
4
|
+
# Part of @kabran-owner/kabran-config
|
|
5
|
+
# Implements PROP-006: JSDoc Traceability Tags
|
|
6
|
+
# ==============================================================================
|
|
7
|
+
|
|
8
|
+
# Version - Dynamically resolve from package.json
|
|
9
|
+
_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
10
|
+
_PKG_JSON="$_SCRIPT_DIR/../../../package.json"
|
|
11
|
+
if [ -f "$_PKG_JSON" ]; then
|
|
12
|
+
TRACEABILITY_VERSION=$(grep '"version":' "$_PKG_JSON" | head -1 | sed -E 's/.*"version": "([^"]+)".*/\1/')
|
|
13
|
+
else
|
|
14
|
+
TRACEABILITY_VERSION="unknown"
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# Colors
|
|
18
|
+
RED='\033[0;31m'
|
|
19
|
+
GREEN='\033[0;32m'
|
|
20
|
+
YELLOW='\033[1;33m'
|
|
21
|
+
BLUE='\033[0;34m'
|
|
22
|
+
GRAY='\033[0;90m'
|
|
23
|
+
NC='\033[0m'
|
|
24
|
+
|
|
25
|
+
# ==============================================================================
|
|
26
|
+
# Logging Functions
|
|
27
|
+
# ==============================================================================
|
|
28
|
+
|
|
29
|
+
log_info() {
|
|
30
|
+
echo -e "${BLUE}[INFO]${NC} $1"
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
log_success() {
|
|
34
|
+
echo -e "${GREEN}[PASS]${NC} $1"
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
log_error() {
|
|
38
|
+
echo -e "${RED}[FAIL]${NC} $1"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
log_warn() {
|
|
42
|
+
echo -e "${YELLOW}[WARN]${NC} $1"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
log_section() {
|
|
46
|
+
echo -e "\n${BLUE}====${NC} $1 ${BLUE}====${NC}"
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# ==============================================================================
|
|
50
|
+
# Tag Patterns (PROP-006 Standard)
|
|
51
|
+
# ==============================================================================
|
|
52
|
+
|
|
53
|
+
# Valid @spec format: @spec SXX (ID only, not full name)
|
|
54
|
+
PATTERN_SPEC_VALID='@spec S[0-9]+'
|
|
55
|
+
PATTERN_SPEC_INVALID='@spec S[0-9]+-'
|
|
56
|
+
|
|
57
|
+
# Valid @implements format: @implements AC-XX or @implements SXX:AC-XX
|
|
58
|
+
PATTERN_IMPLEMENTS='@implements'
|
|
59
|
+
|
|
60
|
+
# Valid @task format: @task XXX-NNN
|
|
61
|
+
PATTERN_TASK='@task [A-Z]+-[0-9]+'
|
|
62
|
+
|
|
63
|
+
# Valid @prd format: @prd RF-XXX or @prd RNF-XXX
|
|
64
|
+
PATTERN_PRD='@prd R(N)?F-[0-9]+'
|
|
65
|
+
|
|
66
|
+
# ==============================================================================
|
|
67
|
+
# Validation Functions
|
|
68
|
+
# ==============================================================================
|
|
69
|
+
|
|
70
|
+
# Check if a file has @implements without @spec (integrity error)
|
|
71
|
+
# Usage: check_orphan_implements "path/to/file.ts"
|
|
72
|
+
# Returns: 0 if valid, 1 if orphan found
|
|
73
|
+
check_orphan_implements() {
|
|
74
|
+
local file="$1"
|
|
75
|
+
|
|
76
|
+
if grep -qE "$PATTERN_IMPLEMENTS" "$file" 2>/dev/null; then
|
|
77
|
+
if ! grep -qE "$PATTERN_SPEC_VALID" "$file" 2>/dev/null; then
|
|
78
|
+
return 1 # Orphan found
|
|
79
|
+
fi
|
|
80
|
+
fi
|
|
81
|
+
return 0 # Valid
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
# Check if a file uses invalid @spec format (full name instead of ID)
|
|
85
|
+
# Usage: check_spec_format "path/to/file.ts"
|
|
86
|
+
# Returns: 0 if valid, 1 if invalid format found
|
|
87
|
+
check_spec_format() {
|
|
88
|
+
local file="$1"
|
|
89
|
+
|
|
90
|
+
if grep -qE "$PATTERN_SPEC_INVALID" "$file" 2>/dev/null; then
|
|
91
|
+
return 1 # Invalid format
|
|
92
|
+
fi
|
|
93
|
+
return 0 # Valid
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
# Extract all @spec tags from a file
|
|
97
|
+
# Usage: extract_specs "path/to/file.ts"
|
|
98
|
+
extract_specs() {
|
|
99
|
+
local file="$1"
|
|
100
|
+
grep -oE '@spec S[0-9]+' "$file" 2>/dev/null | sed 's/@spec //' | sort -u
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
# Extract all @implements tags from a file
|
|
104
|
+
# Usage: extract_implements "path/to/file.ts"
|
|
105
|
+
extract_implements() {
|
|
106
|
+
local file="$1"
|
|
107
|
+
grep -oE '@implements [^*]+' "$file" 2>/dev/null | sed 's/@implements //' | tr ',' '\n' | sed 's/^ *//' | sort -u
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
# Count files with traceability tags
|
|
111
|
+
# Usage: count_tagged_files "path/to/search"
|
|
112
|
+
count_tagged_files() {
|
|
113
|
+
local search_path="${1:-.}"
|
|
114
|
+
grep -rl "@spec" --include="*.ts" --include="*.tsx" "$search_path" 2>/dev/null | wc -l
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
# Count total TypeScript files
|
|
118
|
+
# Usage: count_total_files "path/to/search"
|
|
119
|
+
count_total_files() {
|
|
120
|
+
local search_path="${1:-.}"
|
|
121
|
+
find "$search_path" -type f \( -name "*.ts" -o -name "*.tsx" \) 2>/dev/null | wc -l
|
|
122
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ==============================================================================
|
|
3
|
+
# Kabran Traceability Validator
|
|
4
|
+
# Part of @kabran-owner/kabran-config
|
|
5
|
+
# Implements PROP-006: JSDoc Traceability Tags
|
|
6
|
+
#
|
|
7
|
+
# Validates FORMAT of traceability tags (not presence).
|
|
8
|
+
# Tags are optional - this script only checks:
|
|
9
|
+
# 1. @implements without @spec (integrity error)
|
|
10
|
+
# 2. @spec with full name instead of ID (format warning)
|
|
11
|
+
# ==============================================================================
|
|
12
|
+
|
|
13
|
+
set -uo pipefail
|
|
14
|
+
|
|
15
|
+
# Source core functions
|
|
16
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
17
|
+
# shellcheck source=traceability-core.sh
|
|
18
|
+
source "$SCRIPT_DIR/traceability-core.sh"
|
|
19
|
+
|
|
20
|
+
# ==============================================================================
|
|
21
|
+
# Configuration
|
|
22
|
+
# ==============================================================================
|
|
23
|
+
|
|
24
|
+
SEARCH_PATH="${1:-.}"
|
|
25
|
+
STRICT_MODE="${STRICT_MODE:-false}"
|
|
26
|
+
EXIT_CODE=0
|
|
27
|
+
|
|
28
|
+
# ==============================================================================
|
|
29
|
+
# Main Validation
|
|
30
|
+
# ==============================================================================
|
|
31
|
+
|
|
32
|
+
main() {
|
|
33
|
+
log_section "Traceability Validation v${TRACEABILITY_VERSION}"
|
|
34
|
+
log_info "Search path: $SEARCH_PATH"
|
|
35
|
+
log_info "Strict mode: $STRICT_MODE"
|
|
36
|
+
|
|
37
|
+
local orphan_count=0
|
|
38
|
+
local format_count=0
|
|
39
|
+
local files_checked=0
|
|
40
|
+
|
|
41
|
+
# Find all TypeScript files
|
|
42
|
+
local files
|
|
43
|
+
files=$(find "$SEARCH_PATH" -type f \( -name "*.ts" -o -name "*.tsx" \) 2>/dev/null || true)
|
|
44
|
+
|
|
45
|
+
if [ -z "$files" ]; then
|
|
46
|
+
log_info "No TypeScript files found"
|
|
47
|
+
return 0
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
while IFS= read -r file; do
|
|
51
|
+
[ -z "$file" ] && continue
|
|
52
|
+
files_checked=$((files_checked + 1))
|
|
53
|
+
|
|
54
|
+
# Check for orphan @implements (ERROR)
|
|
55
|
+
if ! check_orphan_implements "$file"; then
|
|
56
|
+
log_error "Orphan @implements (no @spec): $file"
|
|
57
|
+
orphan_count=$((orphan_count + 1))
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# Check for invalid @spec format (WARNING)
|
|
61
|
+
if ! check_spec_format "$file"; then
|
|
62
|
+
log_warn "Invalid @spec format (use ID only): $file"
|
|
63
|
+
format_count=$((format_count + 1))
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
done <<< "$files"
|
|
67
|
+
|
|
68
|
+
# Summary
|
|
69
|
+
log_section "Validation Summary"
|
|
70
|
+
log_info "Files checked: $files_checked"
|
|
71
|
+
|
|
72
|
+
if [ "$orphan_count" -gt 0 ]; then
|
|
73
|
+
log_error "Orphan @implements found: $orphan_count"
|
|
74
|
+
EXIT_CODE=1
|
|
75
|
+
else
|
|
76
|
+
log_success "No orphan @implements found"
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
if [ "$format_count" -gt 0 ]; then
|
|
80
|
+
log_warn "Invalid @spec format: $format_count"
|
|
81
|
+
if [ "$STRICT_MODE" = "true" ]; then
|
|
82
|
+
EXIT_CODE=1
|
|
83
|
+
fi
|
|
84
|
+
else
|
|
85
|
+
log_success "All @spec tags use correct format"
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# Coverage stats (informational)
|
|
89
|
+
local tagged_files
|
|
90
|
+
local total_files
|
|
91
|
+
tagged_files=$(count_tagged_files "$SEARCH_PATH")
|
|
92
|
+
total_files=$(count_total_files "$SEARCH_PATH")
|
|
93
|
+
|
|
94
|
+
if [ "$total_files" -gt 0 ]; then
|
|
95
|
+
local coverage=$((tagged_files * 100 / total_files))
|
|
96
|
+
log_info "Traceability coverage: $tagged_files/$total_files files ($coverage%)"
|
|
97
|
+
fi
|
|
98
|
+
|
|
99
|
+
return $EXIT_CODE
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
# ==============================================================================
|
|
103
|
+
# Help
|
|
104
|
+
# ==============================================================================
|
|
105
|
+
|
|
106
|
+
show_help() {
|
|
107
|
+
cat << EOF
|
|
108
|
+
Kabran Traceability Validator v${TRACEABILITY_VERSION}
|
|
109
|
+
|
|
110
|
+
Usage: validate-traceability.sh [path] [options]
|
|
111
|
+
|
|
112
|
+
Arguments:
|
|
113
|
+
path Directory to validate (default: current directory)
|
|
114
|
+
|
|
115
|
+
Environment Variables:
|
|
116
|
+
STRICT_MODE If "true", format warnings become errors (default: false)
|
|
117
|
+
|
|
118
|
+
Exit Codes:
|
|
119
|
+
0 Validation passed
|
|
120
|
+
1 Validation failed (orphan @implements or strict mode violations)
|
|
121
|
+
|
|
122
|
+
Examples:
|
|
123
|
+
validate-traceability.sh ./src
|
|
124
|
+
STRICT_MODE=true validate-traceability.sh ./src
|
|
125
|
+
|
|
126
|
+
Tags Validated (PROP-006):
|
|
127
|
+
@spec S25 Link to spec (ID only, not full name)
|
|
128
|
+
@implements AC-01 Acceptance criteria implemented
|
|
129
|
+
@task AGT-123 Link to Linear task
|
|
130
|
+
@prd RF-007 Link to PRD requirement
|
|
131
|
+
|
|
132
|
+
Rules:
|
|
133
|
+
- All tags are OPTIONAL
|
|
134
|
+
- @implements WITHOUT @spec is an ERROR
|
|
135
|
+
- @spec with full name (S25-name) is a WARNING
|
|
136
|
+
|
|
137
|
+
EOF
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
# ==============================================================================
|
|
141
|
+
# Entry Point
|
|
142
|
+
# ==============================================================================
|
|
143
|
+
|
|
144
|
+
if [[ "${1:-}" == "--help" ]] || [[ "${1:-}" == "-h" ]]; then
|
|
145
|
+
show_help
|
|
146
|
+
exit 0
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
main
|
|
150
|
+
exit $EXIT_CODE
|