Files
gh-netresearch-claude-code-…/skills/agents/scripts/extract-commands.sh
2025-11-30 08:43:13 +08:00

184 lines
5.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# Extract build commands from various build tool files
set -euo pipefail
PROJECT_DIR="${1:-.}"
cd "$PROJECT_DIR"
# Get project info
PROJECT_INFO=$(bash "$(dirname "$0")/detect-project.sh" "$PROJECT_DIR")
LANGUAGE=$(echo "$PROJECT_INFO" | jq -r '.language')
BUILD_TOOL=$(echo "$PROJECT_INFO" | jq -r '.build_tool')
# Initialize command variables
TYPECHECK_CMD=""
LINT_CMD=""
FORMAT_CMD=""
TEST_CMD=""
BUILD_CMD=""
DEV_CMD=""
# Extract from Makefile
extract_from_makefile() {
[ ! -f "Makefile" ] && return
# Extract targets with ## comments
while IFS= read -r line; do
if [[ $line =~ ^([a-zA-Z_-]+):.*\#\#(.*)$ ]]; then
target="${BASH_REMATCH[1]}"
description="${BASH_REMATCH[2]}"
case "$target" in
lint|check) LINT_CMD="make $target" ;;
format|fmt) FORMAT_CMD="make $target" ;;
test|tests) TEST_CMD="make $target" ;;
build) BUILD_CMD="make $target" ;;
typecheck|types) TYPECHECK_CMD="make $target" ;;
dev|serve) DEV_CMD="make $target" ;;
esac
fi
done < Makefile
}
# Extract from package.json
extract_from_package_json() {
[ ! -f "package.json" ] && return
TYPECHECK_CMD=$(jq -r '.scripts.typecheck // .scripts["type-check"] // empty' package.json 2>/dev/null)
[ -n "$TYPECHECK_CMD" ] && TYPECHECK_CMD="npm run typecheck" || TYPECHECK_CMD="npx tsc --noEmit"
LINT_CMD=$(jq -r '.scripts.lint // empty' package.json 2>/dev/null)
[ -n "$LINT_CMD" ] && LINT_CMD="npm run lint" || LINT_CMD="npx eslint ."
FORMAT_CMD=$(jq -r '.scripts.format // empty' package.json 2>/dev/null)
[ -n "$FORMAT_CMD" ] && FORMAT_CMD="npm run format" || FORMAT_CMD="npx prettier --write ."
TEST_CMD=$(jq -r '.scripts.test // empty' package.json 2>/dev/null)
[ -n "$TEST_CMD" ] && TEST_CMD="npm test"
BUILD_CMD=$(jq -r '.scripts.build // empty' package.json 2>/dev/null)
[ -n "$BUILD_CMD" ] && BUILD_CMD="npm run build"
DEV_CMD=$(jq -r '.scripts.dev // .scripts.start // empty' package.json 2>/dev/null)
[ -n "$DEV_CMD" ] && DEV_CMD="npm run dev"
}
# Extract from composer.json
extract_from_composer_json() {
[ ! -f "composer.json" ] && return
LINT_CMD=$(jq -r '.scripts.lint // .scripts["cs:check"] // empty' composer.json 2>/dev/null)
[ -n "$LINT_CMD" ] && LINT_CMD="composer run lint"
FORMAT_CMD=$(jq -r '.scripts.format // .scripts["cs:fix"] // empty' composer.json 2>/dev/null)
[ -n "$FORMAT_CMD" ] && FORMAT_CMD="composer run format"
TEST_CMD=$(jq -r '.scripts.test // empty' composer.json 2>/dev/null)
[ -n "$TEST_CMD" ] && TEST_CMD="composer run test" || TEST_CMD="vendor/bin/phpunit"
TYPECHECK_CMD=$(jq -r '.scripts.phpstan // .scripts["stan"] // empty' composer.json 2>/dev/null)
[ -n "$TYPECHECK_CMD" ] && TYPECHECK_CMD="composer run phpstan" || {
if [ -f "phpstan.neon" ] || [ -f "Build/phpstan.neon" ]; then
TYPECHECK_CMD="vendor/bin/phpstan analyze"
fi
}
}
# Extract from pyproject.toml
extract_from_pyproject() {
[ ! -f "pyproject.toml" ] && return
# Check for ruff
if grep -q '\[tool.ruff\]' pyproject.toml; then
LINT_CMD="ruff check ."
FORMAT_CMD="ruff format ."
fi
# Check for black
if grep -q 'black' pyproject.toml; then
FORMAT_CMD="black ."
fi
# Check for mypy
if grep -q 'mypy' pyproject.toml; then
TYPECHECK_CMD="mypy ."
fi
# Check for pytest
if grep -q 'pytest' pyproject.toml; then
TEST_CMD="pytest"
fi
}
# Language-specific defaults
set_language_defaults() {
case "$LANGUAGE" in
"go")
[ -z "$TYPECHECK_CMD" ] && TYPECHECK_CMD="go build -v ./..."
[ -z "$LINT_CMD" ] && {
if [ -f ".golangci.yml" ] || [ -f ".golangci.yaml" ]; then
LINT_CMD="golangci-lint run ./..."
fi
}
[ -z "$FORMAT_CMD" ] && FORMAT_CMD="gofmt -w ."
[ -z "$TEST_CMD" ] && TEST_CMD="go test -v -race -short ./..."
[ -z "$BUILD_CMD" ] && BUILD_CMD="go build -v ./..."
;;
"php")
[ -z "$TYPECHECK_CMD" ] && {
if [ -f "phpstan.neon" ] || [ -f "Build/phpstan.neon" ]; then
TYPECHECK_CMD="vendor/bin/phpstan analyze"
fi
}
[ -z "$LINT_CMD" ] && LINT_CMD="vendor/bin/php-cs-fixer fix --dry-run"
[ -z "$FORMAT_CMD" ] && FORMAT_CMD="vendor/bin/php-cs-fixer fix"
[ -z "$TEST_CMD" ] && TEST_CMD="vendor/bin/phpunit"
;;
"typescript")
[ -z "$TYPECHECK_CMD" ] && TYPECHECK_CMD="npx tsc --noEmit"
[ -z "$LINT_CMD" ] && LINT_CMD="npx eslint ."
[ -z "$FORMAT_CMD" ] && FORMAT_CMD="npx prettier --write ."
[ -z "$TEST_CMD" ] && {
if [ -f "jest.config.js" ] || [ -f "jest.config.ts" ]; then
TEST_CMD="npm test"
elif grep -q 'vitest' package.json 2>/dev/null; then
TEST_CMD="npx vitest"
fi
}
;;
"python")
[ -z "$LINT_CMD" ] && LINT_CMD="ruff check ."
[ -z "$FORMAT_CMD" ] && FORMAT_CMD="ruff format ."
[ -z "$TYPECHECK_CMD" ] && TYPECHECK_CMD="mypy ."
[ -z "$TEST_CMD" ] && TEST_CMD="pytest"
;;
esac
}
# Run extraction
extract_from_makefile
extract_from_package_json
extract_from_composer_json
extract_from_pyproject
set_language_defaults
# Output JSON
jq -n \
--arg typecheck "$TYPECHECK_CMD" \
--arg lint "$LINT_CMD" \
--arg format "$FORMAT_CMD" \
--arg test "$TEST_CMD" \
--arg build "$BUILD_CMD" \
--arg dev "$DEV_CMD" \
'{
typecheck: $typecheck,
lint: $lint,
format: $format,
test: $test,
build: $build,
dev: $dev
}'