Skip to content

Commit 3cba3ad

Browse files
committed
feat: add hooks-only mode for JavaScript/TypeScript projects
- Add -J flag for hooks-only installation (no PHP tools) - Auto-detect JS/TS projects when no composer.json found - Add TypeScript type-checking tool (tsc --noEmit) - Add project type selection to interactive wizard - Update version stamp to track installation mode - Skip PHP dependencies check in hooks-only mode - Update documentation with JS/TS quick start guide
1 parent 15685ce commit 3cba3ad

File tree

8 files changed

+301
-87
lines changed

8 files changed

+301
-87
lines changed

booster/.husky/shared/tools.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import type { ToolConfig } from './types.ts'
1010
*
1111
* Tool groups for selective execution (HOOKS_ONLY env var):
1212
* - 'format': Formatting tools (Prettier, ECS)
13-
* - 'lint': Linting tools (ESLint, Stylelint, PHP Syntax)
13+
* - 'lint': Linting tools (ESLint, Stylelint, PHP Syntax, TypeScript)
1414
* - 'analysis': Static analysis (PHPStan, Psalm, Deptrac)
1515
* - 'refactor': Code refactoring (Rector)
1616
*/
@@ -61,6 +61,16 @@ export const TOOLS: ToolConfig[] = [
6161
extensions: ['.vue', '.css', '.scss', '.sass', '.less'],
6262
group: 'lint',
6363
},
64+
{
65+
name: 'TypeScript',
66+
command: 'tsc',
67+
args: ['--noEmit', '--skipLibCheck'],
68+
type: 'node',
69+
passFiles: false, // tsc uses tsconfig.json, not file list
70+
extensions: ['.ts', '.tsx'],
71+
group: 'lint',
72+
description: 'Type-checking TypeScript files...',
73+
},
6474

6575
// PHP Tools
6676
{

booster/integrate_booster.sh

Lines changed: 133 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ function get_installed_version() {
8585
# Create or update the version stamp file
8686
function create_version_stamp() {
8787
local version="$1"
88+
local install_mode="${2:-full}"
8889
local version_file=".booster-version"
8990
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
9091

@@ -96,9 +97,10 @@ function create_version_stamp() {
9697
VERSION=$version
9798
INSTALLED_DATE=$timestamp
9899
INTEGRATION_METHOD=script
100+
INSTALL_MODE=$install_mode
99101
EOF
100102

101-
log "Created version stamp: $version (installed $timestamp)"
103+
log "Created version stamp: $version (installed $timestamp, mode: $install_mode)"
102104
}
103105

104106
# Show version information and upgrade status
@@ -191,7 +193,50 @@ function confirm_action() {
191193
fi
192194
}
193195

196+
function select_project_type() {
197+
echo ""
198+
echo ""
199+
echo "═══════════════════════════════════════════════════════════════"
200+
info "Step 0: Select Project Type"
201+
echo "═══════════════════════════════════════════════════════════════"
202+
echo ""
203+
echo ""
204+
echo "What type of project is this?"
205+
echo ""
206+
echo " 1. PHP Project (full tooling: ECS, Rector, PHPStan, Psalm, etc.)"
207+
echo " 2. JavaScript/TypeScript Project (hooks only: ESLint, Prettier, TypeScript)"
208+
echo ""
209+
210+
# Auto-detect based on files present
211+
local default_type="1"
212+
if [ ! -f "composer.json" ] && [ -f "package.json" ]; then
213+
default_type="2"
214+
info "Detected: No composer.json, but package.json exists. Suggesting JS/TS mode."
215+
elif [ -f "composer.json" ]; then
216+
info "Detected: composer.json exists. Suggesting PHP mode."
217+
fi
218+
219+
prompt "Select project type [1/2] (default: $default_type): "
220+
read -r project_choice
221+
project_choice=${project_choice:-$default_type}
222+
223+
if [ "$project_choice" = "2" ]; then
224+
HOOKS_ONLY_MODE=true
225+
success "JavaScript/TypeScript mode selected (hooks only)"
226+
else
227+
HOOKS_ONLY_MODE=false
228+
success "PHP mode selected (full tooling)"
229+
fi
230+
echo ""
231+
}
232+
194233
function select_tools_to_install() {
234+
# Skip PHP tool selection in hooks-only mode
235+
if [ "$HOOKS_ONLY_MODE" = true ]; then
236+
log "Skipping PHP tool selection (hooks-only mode)"
237+
return
238+
fi
239+
195240
echo ""
196241
echo ""
197242
echo "═══════════════════════════════════════════════════════════════"
@@ -304,11 +349,20 @@ function show_configuration_summary() {
304349
echo "═══════════════════════════════════════════════════════════════"
305350
echo ""
306351
echo ""
307-
echo "📦 Tools to install:"
308-
echo ""
309-
for tool in "${INTERACTIVE_TOOLS_SELECTED[@]}"; do
310-
echo "$tool"
311-
done
352+
353+
echo "🏗️ Project Type:"
354+
if [ "$HOOKS_ONLY_MODE" = true ]; then
355+
echo " ✓ JavaScript/TypeScript (hooks only)"
356+
echo " ✓ Tools: ESLint, Prettier, Stylelint, TypeScript"
357+
else
358+
echo " ✓ PHP (full tooling)"
359+
echo ""
360+
echo "📦 PHP Tools to install:"
361+
echo ""
362+
for tool in "${INTERACTIVE_TOOLS_SELECTED[@]}"; do
363+
echo "$tool"
364+
done
365+
fi
312366
echo ""
313367
echo ""
314368

@@ -427,6 +481,7 @@ function show_post_installation_summary() {
427481

428482
function run_interactive_mode() {
429483
show_welcome_banner
484+
select_project_type
430485
select_tools_to_install
431486
configure_git_workflow
432487
configure_ide_settings
@@ -439,14 +494,18 @@ function check_dependencies() {
439494
log "Checking dependencies..."
440495
local missing_deps=()
441496
command -v jq >/dev/null 2>&1 || missing_deps+=("jq")
442-
command -v yq >/dev/null 2>&1 || missing_deps+=("yq") # Still needed for ddev config
443497
command -v curl >/dev/null 2>&1 || missing_deps+=("curl")
444498
command -v unzip >/dev/null 2>&1 || missing_deps+=("unzip")
445499

446-
if [ $IS_DDEV_PROJECT -eq 1 ]; then
447-
command -v ddev >/dev/null 2>&1 || missing_deps+=("ddev")
448-
else
449-
command -v composer >/dev/null 2>&1 || missing_deps+=("composer")
500+
# Skip PHP-related dependency checks in hooks-only mode
501+
if [ "$HOOKS_ONLY_MODE" != true ]; then
502+
command -v yq >/dev/null 2>&1 || missing_deps+=("yq") # Needed for ddev config
503+
504+
if [ $IS_DDEV_PROJECT -eq 1 ]; then
505+
command -v ddev >/dev/null 2>&1 || missing_deps+=("ddev")
506+
else
507+
command -v composer >/dev/null 2>&1 || missing_deps+=("composer")
508+
fi
450509
fi
451510

452511
if [ ${#missing_deps[@]} -ne 0 ]; then
@@ -1431,6 +1490,7 @@ function show_help() {
14311490
echo "OPTIONS:"
14321491
echo " -I Run in interactive mode (recommended for first-time setup)"
14331492
echo " -N Non-interactive mode (skip all prompts, use defaults)"
1493+
echo " -J JavaScript/TypeScript only mode (hooks only, no PHP tools)"
14341494
echo " -v Enable verbose logging"
14351495
echo " -c Skip cleanup (preserve temporary files for debugging)"
14361496
echo " -i Show version information and exit"
@@ -1439,10 +1499,12 @@ function show_help() {
14391499
echo "DESCRIPTION:"
14401500
echo " Integrates PHP Booster tooling into an existing PHP project."
14411501
echo " Supports both standard PHP projects and DDEV environments."
1502+
echo " Use -J flag for JavaScript/TypeScript projects without PHP."
14421503
echo ""
14431504
echo "EXAMPLES:"
14441505
echo " $0 # Run integration with default settings"
14451506
echo " $0 -I # Run in interactive mode (guided setup)"
1507+
echo " $0 -J # Install hooks only (for JS/TS projects)"
14461508
echo " $0 -v # Run with verbose output"
14471509
echo " $0 -i # Show version information"
14481510
echo ""
@@ -1490,30 +1552,46 @@ function show_version_info_and_exit() {
14901552

14911553
function main() {
14921554
# Process command line arguments
1493-
while getopts ":vchiIN" opt; do
1555+
while getopts ":vchiINJ" opt; do
14941556
case $opt in
14951557
v) VERBOSE=true ;;
14961558
c) NO_CLEANUP=true ;;
14971559
h) show_help; exit 0 ;;
14981560
i) show_version_info_and_exit ;;
14991561
I) INTERACTIVE_MODE=true ;;
15001562
N) SKIP_INTERACTIVE=true ;;
1563+
J) HOOKS_ONLY_MODE=true ;;
15011564
\?) error "Invalid option: -$OPTARG. Use -h for help." ;;
15021565
:) error "Option -$OPTARG requires an argument." ;;
15031566
esac
15041567
done
15051568
shift $((OPTIND - 1))
15061569

1507-
log "Starting php-booster integration..."
1570+
# Determine installation mode
1571+
if [ "$HOOKS_ONLY_MODE" = true ]; then
1572+
log "Starting php-booster integration (hooks-only mode for JS/TS projects)..."
1573+
else
1574+
log "Starting php-booster integration..."
1575+
fi
1576+
15081577
IS_DDEV_PROJECT=$(is_ddev_project)
15091578

1510-
if [ $IS_DDEV_PROJECT -eq 1 ]; then
1579+
# Auto-detect hooks-only mode if no composer.json and not explicitly set
1580+
if [ ! -f "composer.json" ] && [ "$HOOKS_ONLY_MODE" != true ] && [ "$INTERACTIVE_MODE" != true ]; then
1581+
info "No composer.json found. Assuming JavaScript/TypeScript project."
1582+
info "Use -J flag explicitly or -I for interactive mode to customize."
1583+
HOOKS_ONLY_MODE=true
1584+
fi
1585+
1586+
if [ "$HOOKS_ONLY_MODE" = true ]; then
1587+
log "Hooks-only mode: PHP tools will be skipped."
1588+
elif [ $IS_DDEV_PROJECT -eq 1 ]; then
15111589
log "DDEV project detected."
15121590
else
15131591
log "Standard PHP project detected (no .ddev directory found)."
15141592
fi
15151593

1516-
if [ ! -f "composer.json" ] && [ ! -d ".git" ]; then
1594+
if [ ! -f "composer.json" ] && [ ! -d ".git" ] && [ "$HOOKS_ONLY_MODE" != true ]; then
15171595
warn "Script might not be running from the project root (composer.json or .git not found). Results may be unexpected."
15181596
fi
15191597

@@ -1534,43 +1612,57 @@ function main() {
15341612
update_package_json
15351613
update_readme
15361614
update_gitignore
1537-
update_tool_paths
15381615

1539-
# Apply interactive configuration if mode was enabled
1540-
if [ "$INTERACTIVE_MODE" = true ]; then
1541-
apply_interactive_configuration
1542-
fi
1616+
# Skip PHP-specific steps in hooks-only mode
1617+
if [ "$HOOKS_ONLY_MODE" != true ]; then
1618+
update_tool_paths
15431619

1544-
if [ $IS_DDEV_PROJECT -eq 1 ]; then
1545-
log "Updating DDEV files..."
1620+
# Apply interactive configuration if mode was enabled
1621+
if [ "$INTERACTIVE_MODE" = true ]; then
1622+
apply_interactive_configuration
1623+
fi
15461624

1547-
local attempts=0
1548-
local max_attempts=3
1549-
while [ $attempts -lt $max_attempts ]; do
1550-
if ddev start; then
1551-
break
1552-
else
1553-
warn "ddev start failed. Retrying... ($((attempts + 1))/$max_attempts)"
1554-
((attempts++))
1555-
sleep 5
1556-
fi
1557-
done
1558-
update_ddev_files
1559-
update_ddev_config
1560-
update_nginx_config
1561-
ddev restart
1625+
if [ $IS_DDEV_PROJECT -eq 1 ]; then
1626+
log "Updating DDEV files..."
1627+
1628+
local attempts=0
1629+
local max_attempts=3
1630+
while [ $attempts -lt $max_attempts ]; do
1631+
if ddev start; then
1632+
break
1633+
else
1634+
warn "ddev start failed. Retrying... ($((attempts + 1))/$max_attempts)"
1635+
((attempts++))
1636+
sleep 5
1637+
fi
1638+
done
1639+
update_ddev_files
1640+
update_ddev_config
1641+
update_nginx_config
1642+
ddev restart
1643+
fi
1644+
1645+
add_code_quality_tools # Merges composer scripts & installs deps
1646+
init_deptrac
1647+
else
1648+
log "Skipping PHP tools installation (hooks-only mode)."
15621649
fi
15631650

1564-
add_code_quality_tools # Merges composer scripts & installs deps
1565-
init_deptrac
15661651
install_node_dependencies
15671652

15681653
# --- Create Version Stamp ---
1569-
create_version_stamp "$current_version"
1654+
local install_mode="full"
1655+
if [ "$HOOKS_ONLY_MODE" = true ]; then
1656+
install_mode="hooks-only"
1657+
fi
1658+
create_version_stamp "$current_version" "$install_mode"
15701659

15711660
success "Integration process completed."
15721661

1573-
if [ $IS_DDEV_PROJECT -eq 1 ]; then
1662+
if [ "$HOOKS_ONLY_MODE" = true ]; then
1663+
success "Hooks-only installation complete. Git hooks are now active for JS/TS projects."
1664+
info "Available tools: ESLint, Prettier, Stylelint, TypeScript (if tsconfig.json exists)"
1665+
elif [ $IS_DDEV_PROJECT -eq 1 ]; then
15741666
success "Please run 'ddev restart' to apply the DDEV configuration changes."
15751667
fi
15761668

booster/src/lib/interactive.sh

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,50 @@ function confirm_action() {
3535
fi
3636
}
3737

38+
function select_project_type() {
39+
echo ""
40+
echo ""
41+
echo "═══════════════════════════════════════════════════════════════"
42+
info "Step 0: Select Project Type"
43+
echo "═══════════════════════════════════════════════════════════════"
44+
echo ""
45+
echo ""
46+
echo "What type of project is this?"
47+
echo ""
48+
echo " 1. PHP Project (full tooling: ECS, Rector, PHPStan, Psalm, etc.)"
49+
echo " 2. JavaScript/TypeScript Project (hooks only: ESLint, Prettier, TypeScript)"
50+
echo ""
51+
52+
# Auto-detect based on files present
53+
local default_type="1"
54+
if [ ! -f "composer.json" ] && [ -f "package.json" ]; then
55+
default_type="2"
56+
info "Detected: No composer.json, but package.json exists. Suggesting JS/TS mode."
57+
elif [ -f "composer.json" ]; then
58+
info "Detected: composer.json exists. Suggesting PHP mode."
59+
fi
60+
61+
prompt "Select project type [1/2] (default: $default_type): "
62+
read -r project_choice
63+
project_choice=${project_choice:-$default_type}
64+
65+
if [ "$project_choice" = "2" ]; then
66+
HOOKS_ONLY_MODE=true
67+
success "JavaScript/TypeScript mode selected (hooks only)"
68+
else
69+
HOOKS_ONLY_MODE=false
70+
success "PHP mode selected (full tooling)"
71+
fi
72+
echo ""
73+
}
74+
3875
function select_tools_to_install() {
76+
# Skip PHP tool selection in hooks-only mode
77+
if [ "$HOOKS_ONLY_MODE" = true ]; then
78+
log "Skipping PHP tool selection (hooks-only mode)"
79+
return
80+
fi
81+
3982
echo ""
4083
echo ""
4184
echo "═══════════════════════════════════════════════════════════════"
@@ -148,11 +191,20 @@ function show_configuration_summary() {
148191
echo "═══════════════════════════════════════════════════════════════"
149192
echo ""
150193
echo ""
151-
echo "📦 Tools to install:"
152-
echo ""
153-
for tool in "${INTERACTIVE_TOOLS_SELECTED[@]}"; do
154-
echo "$tool"
155-
done
194+
195+
echo "🏗️ Project Type:"
196+
if [ "$HOOKS_ONLY_MODE" = true ]; then
197+
echo " ✓ JavaScript/TypeScript (hooks only)"
198+
echo " ✓ Tools: ESLint, Prettier, Stylelint, TypeScript"
199+
else
200+
echo " ✓ PHP (full tooling)"
201+
echo ""
202+
echo "📦 PHP Tools to install:"
203+
echo ""
204+
for tool in "${INTERACTIVE_TOOLS_SELECTED[@]}"; do
205+
echo "$tool"
206+
done
207+
fi
156208
echo ""
157209
echo ""
158210

@@ -271,6 +323,7 @@ function show_post_installation_summary() {
271323

272324
function run_interactive_mode() {
273325
show_welcome_banner
326+
select_project_type
274327
select_tools_to_install
275328
configure_git_workflow
276329
configure_ide_settings

0 commit comments

Comments
 (0)