Merge _configs/ into config/ for single configuration directory. Update all path references. Changes: - Move _configs/* to config/ - Update .gitignore for new patterns - No code references to _configs/ found Impact: -1 root directory (layout_conventions.md compliance)
419 lines
12 KiB
Plaintext
Executable File
419 lines
12 KiB
Plaintext
Executable File
#!/usr/bin/env nu
|
|
# Install all syntaxis targets with configurations and wrapper scripts
|
|
#
|
|
# Usage:
|
|
# ./scripts/install-all-targets.nu
|
|
# ./scripts/install-all-targets.nu --config-dir ~/.config/syntaxis
|
|
# ./scripts/install-all-targets.nu --install-dir /usr/local/bin
|
|
#
|
|
# Creates:
|
|
# - Configuration files for each target
|
|
# - Wrapper scripts to run with proper configs
|
|
# - Data directories for persistence
|
|
|
|
use std log
|
|
|
|
def main [
|
|
--config-dir: string = "" # Where to place config files (default: ~/.config/syntaxis)
|
|
--install-dir: string = "" # Where to install binaries (default: ~/.local/bin)
|
|
--data-dir: string = "" # Where to store data/databases (default: ~/.local/share/syntaxis)
|
|
--skip-api # Skip syntaxis-api installation
|
|
--skip-tui # Skip syntaxis-tui installation
|
|
--skip-dashboard # Skip syntaxis-dashboard installation
|
|
] {
|
|
log info "🚀 Installing Lifecycle Targets..."
|
|
print ""
|
|
|
|
# Determine directories
|
|
let config_dir = if ($config_dir == "") {
|
|
$"($env.HOME)/.config/syntaxis"
|
|
} else {
|
|
$config_dir
|
|
}
|
|
|
|
let install_dir = if ($install_dir == "") {
|
|
$"($env.HOME)/.local/bin"
|
|
} else {
|
|
$install_dir
|
|
}
|
|
|
|
let data_dir = if ($data_dir == "") {
|
|
$"($env.HOME)/.local/share/syntaxis"
|
|
} else {
|
|
$data_dir
|
|
}
|
|
|
|
let project_root = pwd
|
|
|
|
# Create directories
|
|
mkdir $config_dir | ignore
|
|
mkdir $install_dir | ignore
|
|
mkdir $data_dir | ignore
|
|
log info $"✓ Created directories in ($config_dir)"
|
|
|
|
# Install syntaxis-api (API)
|
|
if not $skip_api {
|
|
install_api $config_dir $install_dir $data_dir $project_root
|
|
}
|
|
|
|
# Install syntaxis-tui
|
|
if not $skip_tui {
|
|
install_tui $config_dir $install_dir $data_dir $project_root
|
|
}
|
|
|
|
# Install syntaxis-dashboard
|
|
if not $skip_dashboard {
|
|
install_dashboard $config_dir $install_dir $data_dir $project_root
|
|
}
|
|
|
|
print ""
|
|
print $"(ansi green)✅ Installation Complete!(ansi reset)"
|
|
print ""
|
|
print "Configuration files:"
|
|
print $" ($config_dir)/syntaxis-api.toml"
|
|
print $" ($config_dir)/syntaxis-tui.toml"
|
|
print $" ($config_dir)/syntaxis-dashboard.toml"
|
|
print ""
|
|
print "Wrapper scripts (binaries resolved from PATH):"
|
|
print $" ($install_dir)/syntaxis-api.sh"
|
|
print $" ($install_dir)/syntaxis-tui.sh"
|
|
print $" ($install_dir)/syntaxis-dashboard.sh"
|
|
print ""
|
|
print "Data directory:"
|
|
print $" ($data_dir)"
|
|
print ""
|
|
print "Quick Start:"
|
|
print $" # Terminal 1 - Start API server"
|
|
print $" syntaxis-api.sh"
|
|
print ""
|
|
print $" # Terminal 2 - Start Dashboard"
|
|
print $" syntaxis-dashboard.sh"
|
|
print ""
|
|
print $" # Terminal 3 - Start TUI"
|
|
print $" syntaxis-tui.sh"
|
|
print ""
|
|
}
|
|
|
|
def install_api [config_dir, install_dir, data_dir, project_root] {
|
|
log info "📦 Installing syntaxis-api..."
|
|
|
|
let binary = $"($project_root)/target/release/syntaxis-api"
|
|
if not ($binary | path exists) {
|
|
log warn $"Binary not found in: ($binary)"
|
|
log info " Binary will be resolved from PATH (ensure 'cargo install' was run)"
|
|
}
|
|
|
|
let config_file = $"($config_dir)/syntaxis-api.toml"
|
|
let features_dir = $"($config_dir)/configs/features"
|
|
|
|
# Create features directory structure
|
|
mkdir $features_dir | ignore
|
|
log info $"✓ Created features directory: ($features_dir)"
|
|
|
|
# Create MAIN config file (Tier 1)
|
|
let config_content = $"# Lifecycle Server Configuration (Main)
|
|
[server]
|
|
host = \"127.0.0.1\"
|
|
port = 3000
|
|
database_path = \"($data_dir)/syntaxis.db\"
|
|
cors_enabled = true
|
|
log_level = \"info\"
|
|
public_files_path = \"./public\"
|
|
|
|
[server.tls]
|
|
enabled = false
|
|
# cert_path = \"/path/to/cert.pem\"
|
|
# key_path = \"/path/to/key.pem\"
|
|
|
|
# Feature Flags - Tier 2 features
|
|
[server.features.database]
|
|
enabled = true
|
|
|
|
[server.features.health]
|
|
enabled = true
|
|
|
|
[server.features.metrics]
|
|
enabled = false
|
|
|
|
[server.features.rate_limit]
|
|
enabled = false
|
|
|
|
[server.features.auth]
|
|
enabled = false
|
|
|
|
[server.features.cache]
|
|
enabled = false
|
|
|
|
[server.features.multi_tenant]
|
|
enabled = false
|
|
"
|
|
|
|
$config_content | save -f $config_file
|
|
log info $"✓ Created main config: ($config_file)"
|
|
|
|
# Create FEATURE configs (Tier 2)
|
|
create_feature_config $features_dir "database" $"[database]
|
|
migrations_path = \"./migrations\"
|
|
auto_migrate = true
|
|
connection_pool_size = 10
|
|
log_queries = false
|
|
"
|
|
|
|
create_feature_config $features_dir "health" $"[health]
|
|
database_timeout_ms = 5000
|
|
include_version = true
|
|
include_uptime = true
|
|
include_database_status = true
|
|
"
|
|
|
|
create_feature_config $features_dir "metrics" $"[metrics]
|
|
metrics_path = \"/metrics\"
|
|
request_duration_buckets = [1, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000]
|
|
trace_requests = false
|
|
collect_performance_metrics = true
|
|
track_memory = true
|
|
"
|
|
|
|
create_feature_config $features_dir "rate_limit" $"[rate_limit]
|
|
requests_per_second = 10
|
|
burst_size = 20
|
|
rate_limit_health_metrics = false
|
|
rate_limit_message = \"Too many requests\"
|
|
"
|
|
|
|
create_feature_config $features_dir "auth" $"[auth]
|
|
api_keys = []
|
|
auth_header = \"Authorization\"
|
|
auth_prefix = \"Bearer\"
|
|
strict_validation = true
|
|
log_failures = true
|
|
"
|
|
|
|
create_feature_config $features_dir "cache" $"[cache]
|
|
backend = \"memory\"
|
|
max_items = 10000
|
|
ttl_seconds = 3600
|
|
|
|
[cache.memory]
|
|
eviction_enabled = true
|
|
eviction_interval_seconds = 300
|
|
|
|
[cache.redis]
|
|
connection_url = \"redis://localhost:6379/0\"
|
|
connection_timeout_ms = 5000
|
|
key_prefix = \"syntaxis:\"
|
|
"
|
|
|
|
create_feature_config $features_dir "multi_tenant" $"[multi_tenant]
|
|
tenant_id_source = \"header\"
|
|
tenant_header_name = \"X-Tenant-ID\"
|
|
require_tenant_id = false
|
|
isolation_level = \"row\"
|
|
allow_schema_customization = false
|
|
max_tenants = 1000
|
|
include_tenant_in_logs = true
|
|
"
|
|
|
|
# Create wrapper script
|
|
# Binary is resolved from PATH (installed via 'cargo install')
|
|
let binary_name = ($binary | path basename)
|
|
let wrapper_file = $"($install_dir)/($binary_name).sh"
|
|
let marker = "# [GENERATED_BY_INSTALL_ALL_TARGETS]"
|
|
let wrapper_content = $"#!/bin/bash
|
|
# Lifecycle Server Wrapper
|
|
$marker
|
|
# Binary resolved from PATH (installed via 'cargo install')
|
|
# Multi-file configuration: main config and feature configs
|
|
|
|
export SYNTAXIS_DATA_DIR=\"($data_dir)\"
|
|
export SYNTAXIS_CONFIG_DIR=\"($config_dir)\"
|
|
export SYNTAXIS_FEATURES_DIR=\"($features_dir)\"
|
|
|
|
exec \"$binary_name\" --config \"($config_file)\" \"\$@\"
|
|
"
|
|
|
|
# Check if wrapper already exists
|
|
if ($wrapper_file | path exists) {
|
|
let existing = open $wrapper_file
|
|
|
|
# Only touch if we generated it (check for marker)
|
|
if ($existing | str contains $marker) {
|
|
if $existing == $wrapper_content {
|
|
log info $"✓ Wrapper already up-to-date: ($wrapper_file)"
|
|
} else {
|
|
$wrapper_content | save -f $wrapper_file
|
|
chmod +x $wrapper_file
|
|
log info $"♻️ Updated wrapper: ($wrapper_file)"
|
|
}
|
|
} else {
|
|
log warn $"⚠️ Wrapper already exists and appears customized (no marker found)"
|
|
log warn $" To regenerate, move/remove: ($wrapper_file)"
|
|
}
|
|
} else {
|
|
$wrapper_content | save -f $wrapper_file
|
|
chmod +x $wrapper_file
|
|
log info $"✓ Created wrapper: ($wrapper_file)"
|
|
}
|
|
}
|
|
|
|
def create_feature_config [features_dir, feature_name, content] {
|
|
let feature_file = $"($features_dir)/($feature_name).toml"
|
|
$content | save -f $feature_file
|
|
log info $" ✓ Feature config: ($feature_file)"
|
|
}
|
|
|
|
def install_tui [config_dir, install_dir, data_dir, project_root] {
|
|
log info "📦 Installing syntaxis-tui..."
|
|
|
|
let binary = $"($project_root)/target/release/syntaxis-tui"
|
|
if not ($binary | path exists) {
|
|
log warn $"Binary not found in: ($binary)"
|
|
log info " Binary will be resolved from PATH (ensure 'cargo install' was run)"
|
|
}
|
|
|
|
let config_file = $"($config_dir)/syntaxis-tui.toml"
|
|
|
|
# Create config file
|
|
let config_content = $"# Lifecycle TUI Configuration
|
|
[tui]
|
|
theme = \"dark\"
|
|
|
|
[database]
|
|
path = \"($data_dir)/syntaxis.db\"
|
|
|
|
[api]
|
|
enabled = false
|
|
base_url = \"http://localhost:3000\"
|
|
auth_token = \"\"
|
|
timeout_secs = 30
|
|
|
|
[ui]
|
|
show_timestamps = true
|
|
confirm_actions = true
|
|
auto_refresh_ms = 5000
|
|
"
|
|
|
|
$config_content | save -f $config_file
|
|
log info $"✓ Created config: ($config_file)"
|
|
|
|
# Create wrapper script
|
|
# Binary is resolved from PATH (installed via 'cargo install')
|
|
let binary_name = ($binary | path basename)
|
|
let wrapper_file = $"($install_dir)/($binary_name).sh"
|
|
let marker = "# [GENERATED_BY_INSTALL_ALL_TARGETS]"
|
|
let wrapper_content = $"#!/bin/bash
|
|
# Lifecycle TUI Wrapper
|
|
$marker
|
|
# Binary resolved from PATH (installed via 'cargo install')
|
|
|
|
export SYNTAXIS_DATA_DIR=\"($data_dir)\"
|
|
export SYNTAXIS_CONFIG_DIR=\"($config_dir)\"
|
|
|
|
# Use local mode by default
|
|
# For remote mode: syntaxis-tui --remote --api-url http://localhost:3000
|
|
|
|
exec \"$binary_name\" \"\$@\"
|
|
"
|
|
|
|
# Check if wrapper already exists
|
|
if ($wrapper_file | path exists) {
|
|
let existing = open $wrapper_file
|
|
|
|
# Only touch if we generated it (check for marker)
|
|
if ($existing | str contains $marker) {
|
|
if $existing == $wrapper_content {
|
|
log info $"✓ Wrapper already up-to-date: ($wrapper_file)"
|
|
} else {
|
|
$wrapper_content | save -f $wrapper_file
|
|
chmod +x $wrapper_file
|
|
log info $"♻️ Updated wrapper: ($wrapper_file)"
|
|
}
|
|
} else {
|
|
log warn $"⚠️ Wrapper already exists and appears customized (no marker found)"
|
|
log warn $" To regenerate, move/remove: ($wrapper_file)"
|
|
}
|
|
} else {
|
|
$wrapper_content | save -f $wrapper_file
|
|
chmod +x $wrapper_file
|
|
log info $"✓ Created wrapper: ($wrapper_file)"
|
|
}
|
|
}
|
|
|
|
def install_dashboard [config_dir, install_dir, data_dir, project_root] {
|
|
log info "📦 Installing syntaxis-dashboard..."
|
|
|
|
let binary = $"($project_root)/target/release/syntaxis-dashboard"
|
|
if not ($binary | path exists) {
|
|
log warn $"Binary not found in: ($binary)"
|
|
log info " Binary will be resolved from PATH (ensure 'cargo install' was run)"
|
|
}
|
|
|
|
let config_file = $"($config_dir)/syntaxis-dashboard.toml"
|
|
|
|
# Create config file
|
|
let config_content = $"# Lifecycle Dashboard Configuration
|
|
[server]
|
|
host = \"0.0.0.0\"
|
|
port = 5173
|
|
dev_server = true
|
|
|
|
[api]
|
|
url = \"http://localhost:3000\"
|
|
timeout_secs = 30
|
|
retries = 3
|
|
|
|
[ui]
|
|
theme = \"auto\"
|
|
language = \"en\"
|
|
|
|
[features]
|
|
enable_realtime_updates = true
|
|
enable_export = true
|
|
enable_advanced_analytics = true
|
|
"
|
|
|
|
$config_content | save -f $config_file
|
|
log info $"✓ Created config: ($config_file)"
|
|
|
|
# Create wrapper script
|
|
# Binary is resolved from PATH (installed via 'cargo install')
|
|
let binary_name = ($binary | path basename)
|
|
let wrapper_file = $"($install_dir)/($binary_name).sh"
|
|
let marker = "# [GENERATED_BY_INSTALL_ALL_TARGETS]"
|
|
let wrapper_content = $"#!/bin/bash
|
|
# Lifecycle Dashboard Wrapper
|
|
$marker
|
|
# Binary resolved from PATH (installed via 'cargo install')
|
|
|
|
export SYNTAXIS_DATA_DIR=\"($data_dir)\"
|
|
export SYNTAXIS_CONFIG_DIR=\"($config_dir)\"
|
|
export SYNTAXIS_API_URL=\"http://localhost:3000\"
|
|
export SYNTAXIS_DASHBOARD_PORT=\"5173\"
|
|
|
|
exec \"$binary_name\" \"\$@\"
|
|
"
|
|
|
|
# Check if wrapper already exists
|
|
if ($wrapper_file | path exists) {
|
|
let existing = open $wrapper_file
|
|
|
|
# Only touch if we generated it (check for marker)
|
|
if ($existing | str contains $marker) {
|
|
if $existing == $wrapper_content {
|
|
log info $"✓ Wrapper already up-to-date: ($wrapper_file)"
|
|
} else {
|
|
$wrapper_content | save -f $wrapper_file
|
|
chmod +x $wrapper_file
|
|
log info $"♻️ Updated wrapper: ($wrapper_file)"
|
|
}
|
|
} else {
|
|
log warn $"⚠️ Wrapper already exists and appears customized (no marker found)"
|
|
log warn $" To regenerate, move/remove: ($wrapper_file)"
|
|
}
|
|
} else {
|
|
$wrapper_content | save -f $wrapper_file
|
|
chmod +x $wrapper_file
|
|
log info $"✓ Created wrapper: ($wrapper_file)"
|
|
}
|
|
}
|