feature: Initial commit

This commit is contained in:
Keith Solomon
2025-10-25 16:55:22 -05:00
commit 3e779343b2
8 changed files with 642 additions and 0 deletions

169
windows/wp-bootstrap.ps1 Normal file
View File

@@ -0,0 +1,169 @@
Param(
[Parameter(Mandatory=$true)][string]$ProjectName,
[string]$AdminUser = "vdidev",
[string]$AdminEmail = "dev@vincentdesign.ca",
[string]$ThemeStarterRepo = "https://github.com/vincent-design-inc/starter-theme-3.git",
[string]$HerdWorkspace = "$HOME\Herd",
[string]$LocalTld = "test",
[string]$MysqlHost = "127.0.0.1",
[string]$MysqlPort = "3306",
[string]$MysqlRootUser = "root",
[string]$MysqlRootPass = "",
# If WP-CLI isn't globally installed, set this to 'php .\wp-cli.phar'
[string]$WpCliPath = "wp"
)
function Slugify([string]$s) { ($s.ToLower() -replace '[^a-z0-9]+','-').Trim('-') }
function RandPass() {
$bytes = New-Object 'System.Byte[]' 18
(New-Object System.Security.Cryptography.RNGCryptoServiceProvider).GetBytes($bytes)
[Convert]::ToBase64String($bytes) -replace '[^a-zA-Z0-9]','' | ForEach-Object { $_.Substring(0,24) }
}
function Invoke-WP {
param([string[]]$Args)
# Support 'wp' OR 'php .\wp-cli.phar'
if ($WpCliPath -match '\s') {
$parts = $WpCliPath -split '\s+'
& $parts[0] $parts[1..($parts.Count-1)] $Args 2>&1 | ForEach-Object { "$_" }
} else {
& $WpCliPath $Args 2>&1 | ForEach-Object { "$_" }
}
if ($LASTEXITCODE -ne 0) { throw "WP-CLI command failed: $($Args -join ' ')" }
}
function WP([string]$line) {
# Convenience to pass a single-line string; splits on spaces
$args = @()
$token = ""
$inQuote = $false
foreach ($c in $line.ToCharArray()) {
if ($c -eq '"') { $inQuote = -not $inQuote; continue }
if (-not $inQuote -and [char]::IsWhiteSpace($c)) {
if ($token.Length -gt 0) { $args += $token; $token = "" }
} else { $token += $c }
}
if ($token.Length -gt 0) { $args += $token }
Invoke-WP $args
}
# === Start ===
$Slug = Slugify $ProjectName
$ProjectDir = Join-Path $HerdWorkspace $Slug
$LocalUrl = "http://$Slug.$LocalTld"
$DbName = "vdi_$Slug"
$DbUser = $DbName
$DbPass = RandPass
$AdminPass = RandPass
Write-Host "Creating project at $ProjectDir..."
New-Item -ItemType Directory -Force -Path $ProjectDir | Out-Null
Set-Location $ProjectDir
# --- WordPress Core ---
Write-Host "Downloading WordPress..."
Invoke-WP @("core","download","--force")
# --- Database setup ---
Write-Host "Creating MySQL DB and user..."
$mysqlArgs = @("-h", $MysqlHost, "-P", $MysqlPort, "-u", $MysqlRootUser)
if ($MysqlRootPass -ne "") { $mysqlArgs += "-p$MysqlRootPass" }
$sql = @"
CREATE DATABASE IF NOT EXISTS `$DbName` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS '$DbUser'@'%' IDENTIFIED BY '$DbPass';
GRANT ALL PRIVILEGES ON `$DbName`.* TO '$DbUser'@'%';
FLUSH PRIVILEGES;
"@
try {
$sql | & mysql.exe @mysqlArgs
} catch {
throw "MySQL client not found or connection failed. Ensure mysql.exe is in PATH and DBngin/MySQL is running."
}
# --- Config + Install ---
Invoke-WP @("config","create","--dbname=$DbName","--dbuser=$DbUser","--dbpass=$DbPass","--dbhost=$MysqlHost`:$MysqlPort","--force")
Invoke-WP @("config","shuffle-salts")
Invoke-WP @("core","install","--url=$LocalUrl","--title=$ProjectName","--admin_user=$AdminUser","--admin_password=$AdminPass","--admin_email=$AdminEmail")
Invoke-WP @("option","update","siteurl",$LocalUrl)
Invoke-WP @("option","update","home",$LocalUrl)
# --- Pages & Reading ---
Write-Host "Creating Home/News pages and setting permalinks..."
$homeId = (Invoke-WP @("post","create","--post_type=page","--post_status=publish","--post_title=Home","--porcelain") | Select-Object -Last 1).Trim()
$newsId = (Invoke-WP @("post","create","--post_type=page","--post_status=publish","--post_title=News","--porcelain") | Select-Object -Last 1).Trim()
Invoke-WP @("option","update","show_on_front","page")
Invoke-WP @("option","update","page_on_front",$homeId)
Invoke-WP @("option","update","page_for_posts",$newsId)
Invoke-WP @("rewrite","structure","/%postname%/")
Invoke-WP @("rewrite","flush","--hard")
# --- Theme ---
Write-Host "Cloning starter theme..."
$tmp = ".starter-tmp"
if (Test-Path $tmp) { Remove-Item -Recurse -Force $tmp }
git clone --depth=1 $ThemeStarterRepo $tmp | Out-Null
$ThemeDir = "wp-content\themes\$Slug-theme"
if (Test-Path $ThemeDir) { Remove-Item -Recurse -Force $ThemeDir }
New-Item -ItemType Directory -Force -Path (Split-Path $ThemeDir) | Out-Null
Move-Item $tmp $ThemeDir
if (Test-Path "$ThemeDir\.git") { Remove-Item -Recurse -Force "$ThemeDir\.git" }
Invoke-WP @("theme","activate","$Slug-theme")
Push-Location $ThemeDir
git init -b main | Out-Null
git add -A
git commit -m "feat: bootstrap ${ProjectName} theme from starter" | Out-Null
Pop-Location
# --- Plugins ---
if (Test-Path "plugins.json") {
try {
$plugins = Get-Content "plugins.json" | ConvertFrom-Json
foreach ($plugin in $plugins) {
if ($plugin.zip) {
$args = @("plugin","install",$plugin.zip,"--force")
if ($plugin.activate -eq $true) { $args += "--activate" }
Invoke-WP $args
} elseif ($plugin.slug) {
$args = @("plugin","install",$plugin.slug,"--force")
if ($plugin.version) { $args += "--version=$($plugin.version)" }
if ($plugin.activate -eq $true) { $args += "--activate" }
Invoke-WP $args
}
}
} catch {
Write-Host "Error reading plugins.json: $_"
}
}
# --- Summary ---
$Summary = @"
VDI WP Bootstrap Summary
===========================
Project: $ProjectName
Slug: $Slug
Folder: $ProjectDir
Local URL: $LocalUrl
DB Host: $MysqlHost
DB Port: $MysqlPort
DB Name: $DbName
DB User: $DbUser
DB Pass: $DbPass
WP Admin User: $AdminUser
WP Admin Pass: $AdminPass
WP Admin Email: $AdminEmail
Theme Dir: $ThemeDir
"@
$SummaryFile = Join-Path $ProjectDir "bootstrap-summary.txt"
$Summary | Out-File -FilePath $SummaryFile -Encoding utf8
Write-Host $Summary
Write-Host "Saved summary to $SummaryFile"