@bostonuniversity/buwp-local 0.6.2 β 0.7.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/bin/buwp-local.js +9 -0
- package/docs/CHANGELOG.md +18 -1
- package/docs/COMMANDS.md +40 -0
- package/docs/GETTING_STARTED.md +3 -0
- package/docs/MIGRATION_FROM_VM.md +1 -1
- package/docs/ROADMAP.md +61 -14
- package/docs/VOLUME_MAPPINGS.md +466 -0
- package/docs/XDEBUG.md +429 -0
- package/lib/commands/destroy.js +1 -1
- package/lib/commands/init.js +37 -35
- package/lib/commands/update.js +113 -0
- package/package.json +2 -2
- package/readme.md +3 -0
- package/MULTI_PROJECT_GUIDE.md +0 -929
- package/PROJECT_OVERVIEW.md +0 -307
- package/QUICK_REFERENCE.md +0 -234
- package/ROADMAP.md +0 -363
- package/USAGE.md +0 -324
- package/docker-compose.yml +0 -106
- package/docs/MULTI_PROJECT.md +0 -513
- package/feedback-from-0-6-1.md +0 -16
package/docs/XDEBUG.md
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
# Xdebug Setup Guide
|
|
2
|
+
|
|
3
|
+
Xdebug configuration depends on your [volume mapping pattern](VOLUME_MAPPINGS.md). The key principle: **pathMappings must match your volume mappings exactly**.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
1. **Enable Xdebug** in `.buwp-local.json`:
|
|
8
|
+
```json
|
|
9
|
+
"env": {
|
|
10
|
+
"XDEBUG": true
|
|
11
|
+
}
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
2. **Restart environment** to apply changes:
|
|
15
|
+
```bash
|
|
16
|
+
npx buwp-local stop
|
|
17
|
+
npx buwp-local start
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
3. **Configure pathMappings** using the pattern-specific examples below.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Pattern A: In-Repo Development
|
|
25
|
+
|
|
26
|
+
**Scenario:** buwp-local lives inside your plugin/theme repo (like wp-env).
|
|
27
|
+
|
|
28
|
+
**Volume mapping:**
|
|
29
|
+
```json
|
|
30
|
+
"mappings": [
|
|
31
|
+
{
|
|
32
|
+
"local": ".",
|
|
33
|
+
"container": "/var/www/html/wp-content/plugins/bu-navigation"
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### VSCode Configuration
|
|
39
|
+
|
|
40
|
+
Create `.vscode/launch.json` in your plugin/theme repo:
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"version": "0.2.0",
|
|
45
|
+
"configurations": [
|
|
46
|
+
{
|
|
47
|
+
"name": "Listen for Xdebug (Pattern A)",
|
|
48
|
+
"type": "php",
|
|
49
|
+
"request": "launch",
|
|
50
|
+
"port": 9003,
|
|
51
|
+
"pathMappings": {
|
|
52
|
+
"/var/www/html/wp-content/plugins/bu-navigation": "${workspaceRoot}"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### PHPStorm Configuration
|
|
60
|
+
|
|
61
|
+
1. Go to **Run β Edit Configurations**
|
|
62
|
+
2. Add **PHP Remote Debug** configuration
|
|
63
|
+
3. Set **Server** configuration:
|
|
64
|
+
- Host: `localhost`
|
|
65
|
+
- Port: `9003`
|
|
66
|
+
- Debugger: `Xdebug`
|
|
67
|
+
4. Add **Path mapping**:
|
|
68
|
+
- Local: `/path/to/bu-navigation` (your repo root)
|
|
69
|
+
- Remote: `/var/www/html/wp-content/plugins/bu-navigation`
|
|
70
|
+
|
|
71
|
+
### Zed Configuration
|
|
72
|
+
|
|
73
|
+
Create `.zed/tasks.json`:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"xdebug": {
|
|
78
|
+
"type": "php",
|
|
79
|
+
"pathMappings": {
|
|
80
|
+
"/var/www/html/wp-content/plugins/bu-navigation": "."
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Pattern B: Sandbox Coordination
|
|
89
|
+
|
|
90
|
+
**Scenario:** Base camp directory maps multiple plugin/theme repos.
|
|
91
|
+
|
|
92
|
+
**Volume mapping:**
|
|
93
|
+
```json
|
|
94
|
+
"mappings": [
|
|
95
|
+
{
|
|
96
|
+
"local": "/Users/jaydub/projects/bu-navigation",
|
|
97
|
+
"container": "/var/www/html/wp-content/plugins/bu-navigation"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"local": "/Users/jaydub/projects/bu-slideshow",
|
|
101
|
+
"container": "/var/www/html/wp-content/plugins/bu-slideshow"
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### VSCode Multi-Root Workspace
|
|
107
|
+
|
|
108
|
+
Create a **workspace file** (e.g., `bu-plugins.code-workspace`) to include all repos:
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"folders": [
|
|
113
|
+
{ "path": "../bu-navigation" },
|
|
114
|
+
{ "path": "../bu-slideshow" }
|
|
115
|
+
],
|
|
116
|
+
"settings": {},
|
|
117
|
+
"launch": {
|
|
118
|
+
"version": "0.2.0",
|
|
119
|
+
"configurations": [
|
|
120
|
+
{
|
|
121
|
+
"name": "Listen for Xdebug (Pattern B)",
|
|
122
|
+
"type": "php",
|
|
123
|
+
"request": "launch",
|
|
124
|
+
"port": 9003,
|
|
125
|
+
"pathMappings": {
|
|
126
|
+
"/var/www/html/wp-content/plugins/bu-navigation": "${workspaceFolder:bu-navigation}",
|
|
127
|
+
"/var/www/html/wp-content/plugins/bu-slideshow": "${workspaceFolder:bu-slideshow}"
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
]
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Usage:**
|
|
136
|
+
1. Open the `.code-workspace` file in VSCode
|
|
137
|
+
2. All mapped repos will be available in the sidebar
|
|
138
|
+
3. Set breakpoints in any repo
|
|
139
|
+
4. Start debugging with F5
|
|
140
|
+
|
|
141
|
+
### PHPStorm Multi-Module Setup
|
|
142
|
+
|
|
143
|
+
1. Open PHPStorm, go to **File β Project Structure**
|
|
144
|
+
2. Add each repo as a **Module**
|
|
145
|
+
3. Configure **Run β Edit Configurations β PHP Remote Debug**
|
|
146
|
+
4. Add path mappings for each repo:
|
|
147
|
+
- `/Users/jaydub/projects/bu-navigation` β `/var/www/html/wp-content/plugins/bu-navigation`
|
|
148
|
+
- `/Users/jaydub/projects/bu-slideshow` β `/var/www/html/wp-content/plugins/bu-slideshow`
|
|
149
|
+
|
|
150
|
+
### Zed Workspace
|
|
151
|
+
|
|
152
|
+
Zed doesn't have multi-root workspace concept. Open each repo separately and configure individually (Pattern A style for each).
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Pattern C: Monolithic Sandbox
|
|
157
|
+
|
|
158
|
+
**Scenario:** Base camp maps entire WordPress installation for complete IDE context.
|
|
159
|
+
|
|
160
|
+
**Volume mapping:**
|
|
161
|
+
```json
|
|
162
|
+
"mappings": [
|
|
163
|
+
{
|
|
164
|
+
"local": "/Users/jaydub/wordpress-builds/bu-prod",
|
|
165
|
+
"container": "/var/www/html"
|
|
166
|
+
}
|
|
167
|
+
]
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### VSCode Configuration
|
|
171
|
+
|
|
172
|
+
Create `.vscode/launch.json` in your WordPress build directory:
|
|
173
|
+
|
|
174
|
+
```json
|
|
175
|
+
{
|
|
176
|
+
"version": "0.2.0",
|
|
177
|
+
"configurations": [
|
|
178
|
+
{
|
|
179
|
+
"name": "Listen for Xdebug (Pattern C)",
|
|
180
|
+
"type": "php",
|
|
181
|
+
"request": "launch",
|
|
182
|
+
"port": 9003,
|
|
183
|
+
"pathMappings": {
|
|
184
|
+
"/var/www/html": "${workspaceRoot}"
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
]
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Advantages:**
|
|
192
|
+
- Single path mapping (simpler)
|
|
193
|
+
- Full WordPress context in IDE
|
|
194
|
+
- Go-to-definition works across all code
|
|
195
|
+
- Autocomplete for WordPress core
|
|
196
|
+
|
|
197
|
+
**Trade-offs:**
|
|
198
|
+
- Slower volume performance on macOS
|
|
199
|
+
- Larger IDE project (may be slower)
|
|
200
|
+
- Must manage entire WordPress build
|
|
201
|
+
|
|
202
|
+
### PHPStorm Configuration
|
|
203
|
+
|
|
204
|
+
1. Open the WordPress build directory as your project root
|
|
205
|
+
2. Configure **PHP Remote Debug**
|
|
206
|
+
3. Add single path mapping:
|
|
207
|
+
- Local: `/Users/jaydub/wordpress-builds/bu-prod`
|
|
208
|
+
- Remote: `/var/www/html`
|
|
209
|
+
|
|
210
|
+
### Zed Configuration
|
|
211
|
+
|
|
212
|
+
Create `.zed/tasks.json` in WordPress root:
|
|
213
|
+
|
|
214
|
+
```json
|
|
215
|
+
{
|
|
216
|
+
"xdebug": {
|
|
217
|
+
"type": "php",
|
|
218
|
+
"pathMappings": {
|
|
219
|
+
"/var/www/html": "."
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Common Setup Steps (All Patterns)
|
|
228
|
+
|
|
229
|
+
### Install PHP Debug Extension (VSCode)
|
|
230
|
+
|
|
231
|
+
1. Open VSCode Extensions (Cmd+Shift+X)
|
|
232
|
+
2. Search for "PHP Debug"
|
|
233
|
+
3. Install: https://marketplace.visualstudio.com/items?itemName=xdebug.php-debug
|
|
234
|
+
|
|
235
|
+
### Start Debugging
|
|
236
|
+
|
|
237
|
+
1. **Set breakpoint** in your PHP file (click left gutter)
|
|
238
|
+
2. **Start debug listener** (F5 or Run β Start Debugging)
|
|
239
|
+
3. **Trigger code** in browser (reload page, submit form, etc.)
|
|
240
|
+
4. **Debugger pauses** at breakpoint
|
|
241
|
+
|
|
242
|
+
### Verify Xdebug is Running
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
# Check Xdebug is loaded
|
|
246
|
+
npx buwp-local wp eval 'phpinfo();' | grep -i xdebug
|
|
247
|
+
|
|
248
|
+
# Or via shell
|
|
249
|
+
npx buwp-local shell
|
|
250
|
+
php -v # Should show "with Xdebug"
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## Alternative: VSCode Remote Container Debugging
|
|
256
|
+
|
|
257
|
+
An alternative to volume mapping is to use VSCode's **Dev Containers** extension to open the entire WordPress container directly in VSCode. PhpStorm also has a similar feature (Zed does not currently support this).
|
|
258
|
+
|
|
259
|
+
### How It Works
|
|
260
|
+
|
|
261
|
+
Instead of syncing code via volume mappings, you open VSCode **inside the container** and edit/debug directly there:
|
|
262
|
+
|
|
263
|
+
1. Start buwp-local (any pattern, even without volume mappings)
|
|
264
|
+
2. Right-click the running container in VSCode Docker explorer
|
|
265
|
+
3. Select "Attach Visual Studio Code"
|
|
266
|
+
4. VSCode opens inside the container with full filesystem access
|
|
267
|
+
5. Set breakpoints and debug the entire build
|
|
268
|
+
|
|
269
|
+
### When to Use This
|
|
270
|
+
|
|
271
|
+
- β
Experimental edits (don't need to persist locally)
|
|
272
|
+
- β
Full WordPress core context needed (like Pattern C)
|
|
273
|
+
- β
Stepping through entire codebase quickly
|
|
274
|
+
- β
Learning/exploring the build
|
|
275
|
+
|
|
276
|
+
### Setup
|
|
277
|
+
|
|
278
|
+
1. **Install Remote Containers Extension** (if not already installed)
|
|
279
|
+
- Open VSCode Extensions (Cmd+Shift+X)
|
|
280
|
+
- Search for "Remote - Containers"
|
|
281
|
+
- Install: https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers
|
|
282
|
+
|
|
283
|
+
2. **Start your environment**
|
|
284
|
+
```bash
|
|
285
|
+
npx buwp-local start
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
3. **Open container in VSCode**
|
|
289
|
+
- Click **Containers** (sidebar)
|
|
290
|
+
- Open the buwp-local project in the Containers list
|
|
291
|
+
- Right-click on the WordPress container β **Attach Visual Studio Code**
|
|
292
|
+
|
|
293
|
+
4. **Install Extensions and Configure Debugging in container**
|
|
294
|
+
- Install PHP Debug extension inside the container VSCode
|
|
295
|
+
- Create `.vscode/launch.json` with pathMappings as needed (usually just `/var/www/html` to `.`)
|
|
296
|
+
|
|
297
|
+
### Advantages vs Volume Mapping
|
|
298
|
+
|
|
299
|
+
| Aspect | Volume Mapping | Remote Container |
|
|
300
|
+
|--------|---|---|
|
|
301
|
+
| **IDE Context** | Pattern-dependent | Full codebase always |
|
|
302
|
+
| **Persistence** | Changes stay local | Temporary only |
|
|
303
|
+
| **Performance** | Fast (local) | Slower (Docker I/O) |
|
|
304
|
+
| **Best For** | Production code changes | Experimental debugging |
|
|
305
|
+
|
|
306
|
+
### When NOT to Use This
|
|
307
|
+
|
|
308
|
+
- β Changes you need to keep locally (use volume mapping instead)
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Troubleshooting
|
|
313
|
+
|
|
314
|
+
### Breakpoints Not Hit
|
|
315
|
+
|
|
316
|
+
**Check pathMappings match your volume mappings:**
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
# View your volume mappings
|
|
320
|
+
npx buwp-local config --show
|
|
321
|
+
|
|
322
|
+
# Ensure pathMappings in launch.json match exactly
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
**Common mistakes:**
|
|
326
|
+
- Pattern A: Using `/var/www/html` instead of full plugin path
|
|
327
|
+
- Pattern B: Missing mappings for some repos
|
|
328
|
+
- Pattern C: Wrong workspace root
|
|
329
|
+
|
|
330
|
+
### "Cannot Find File" Errors
|
|
331
|
+
|
|
332
|
+
**VSCode shows:** "Could not find file /var/www/html/..."
|
|
333
|
+
|
|
334
|
+
**Solution:** Your local file path doesn't match the pathMapping. Check:
|
|
335
|
+
1. Is VSCode workspace root correct?
|
|
336
|
+
2. Does `${workspaceRoot}` resolve to the right path?
|
|
337
|
+
3. For Pattern B, are you using multi-root workspace?
|
|
338
|
+
|
|
339
|
+
### Performance Issues
|
|
340
|
+
|
|
341
|
+
**Xdebug can slow page loads significantly.**
|
|
342
|
+
|
|
343
|
+
**Solutions:**
|
|
344
|
+
- Disable Xdebug when not actively debugging
|
|
345
|
+
- Use conditional breakpoints sparingly
|
|
346
|
+
- Pattern C is slower than A/B due to larger volume mapping
|
|
347
|
+
|
|
348
|
+
### Port Already in Use
|
|
349
|
+
|
|
350
|
+
**Error:** "Port 9003 already in use"
|
|
351
|
+
|
|
352
|
+
**Solution:**
|
|
353
|
+
```bash
|
|
354
|
+
# Find process using port 9003
|
|
355
|
+
lsof -i :9003
|
|
356
|
+
|
|
357
|
+
# Kill if needed
|
|
358
|
+
kill -9 <PID>
|
|
359
|
+
|
|
360
|
+
# Or change Xdebug port in launch.json and container config
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## Advanced Configuration
|
|
366
|
+
|
|
367
|
+
### Conditional Breakpoints
|
|
368
|
+
|
|
369
|
+
Right-click breakpoint in VSCode β Edit Breakpoint β Add expression:
|
|
370
|
+
|
|
371
|
+
```php
|
|
372
|
+
$post_id === 123
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### Step Debugging WP-CLI Commands
|
|
376
|
+
|
|
377
|
+
```bash
|
|
378
|
+
# Enable Xdebug for CLI
|
|
379
|
+
npx buwp-local wp --allow-root eval 'xdebug_break();'
|
|
380
|
+
|
|
381
|
+
# Or set environment variable
|
|
382
|
+
npx buwp-local shell
|
|
383
|
+
export XDEBUG_SESSION=1
|
|
384
|
+
wp plugin list
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Remote Debugging from Browser
|
|
388
|
+
|
|
389
|
+
Install Xdebug browser extension:
|
|
390
|
+
- Chrome: [Xdebug Helper](https://chrome.google.com/webstore/detail/xdebug-helper)
|
|
391
|
+
- Firefox: [Xdebug Helper](https://addons.mozilla.org/en-US/firefox/addon/xdebug-helper-for-firefox/)
|
|
392
|
+
|
|
393
|
+
Click extension icon β Enable debugging β Reload page.
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
## Pattern-Specific Tips
|
|
398
|
+
|
|
399
|
+
### Pattern A (In-Repo)
|
|
400
|
+
- β
Simplest pathMapping setup
|
|
401
|
+
- β No WordPress core debugging
|
|
402
|
+
- π‘ Use [php-stubs/wordpress-stubs](https://github.com/php-stubs/wordpress-stubs) for autocomplete
|
|
403
|
+
|
|
404
|
+
### Pattern B (Sandbox)
|
|
405
|
+
- β
Debug multiple repos simultaneously
|
|
406
|
+
- β οΈ Requires multi-root workspace in VSCode
|
|
407
|
+
- π‘ Create `.code-workspace` file for team to share
|
|
408
|
+
|
|
409
|
+
### Pattern C (Monolithic)
|
|
410
|
+
- β
Debug WordPress core, plugins, themes all together
|
|
411
|
+
- β
Full IDE context (go-to-definition everywhere)
|
|
412
|
+
- β οΈ Larger project, slower performance on macOS
|
|
413
|
+
- π‘ Use sparse checkout to reduce repo size
|
|
414
|
+
|
|
415
|
+
---
|
|
416
|
+
|
|
417
|
+
## Related Documentation
|
|
418
|
+
|
|
419
|
+
- **[VOLUME_MAPPINGS.md](VOLUME_MAPPINGS.md)** - Complete guide to volume mapping patterns
|
|
420
|
+
- **[GETTING_STARTED.md](GETTING_STARTED.md)** - Initial setup guide
|
|
421
|
+
- **[COMMANDS.md](COMMANDS.md)** - CLI reference
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
## References
|
|
426
|
+
|
|
427
|
+
- [Xdebug Documentation](https://xdebug.org/docs/)
|
|
428
|
+
- [VSCode PHP Debugging](https://code.visualstudio.com/docs/languages/php)
|
|
429
|
+
- [PHPStorm Xdebug Guide](https://www.jetbrains.com/help/phpstorm/configuring-xdebug.html)
|
package/lib/commands/destroy.js
CHANGED
|
@@ -85,7 +85,7 @@ function confirmDestroy(projectName) {
|
|
|
85
85
|
console.log(chalk.yellow(`This will destroy project: ${chalk.bold(projectName)}`));
|
|
86
86
|
console.log(chalk.yellow(' - Stop all containers'));
|
|
87
87
|
console.log(chalk.yellow(' - Remove all containers'));
|
|
88
|
-
console.log(chalk.yellow(' - Delete all volumes (including database data)
|
|
88
|
+
console.log(chalk.yellow(' - Delete all volumes (including database data)\n'));
|
|
89
89
|
|
|
90
90
|
rl.question(chalk.red('Are you sure you want to continue? (yes/no): '), (answer) => {
|
|
91
91
|
rl.close();
|
package/lib/commands/init.js
CHANGED
|
@@ -9,6 +9,17 @@ import fs from 'fs';
|
|
|
9
9
|
import os from 'os';
|
|
10
10
|
import { initConfig, CONFIG_FILE_NAME } from '../config.js';
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Container path templates for project types
|
|
14
|
+
* Defines where each project type maps to in the WordPress container
|
|
15
|
+
*/
|
|
16
|
+
const MAPPING_TEMPLATES = {
|
|
17
|
+
'plugin': '/var/www/html/wp-content/plugins/{name}',
|
|
18
|
+
'mu-plugin': '/var/www/html/wp-content/mu-plugins/{name}',
|
|
19
|
+
'theme': '/var/www/html/wp-content/themes/{name}',
|
|
20
|
+
'sandbox': null // Sandbox has no default mapping
|
|
21
|
+
};
|
|
22
|
+
|
|
12
23
|
/**
|
|
13
24
|
* Detect project type from package.json or directory structure
|
|
14
25
|
* @param {string} projectPath - Path to project directory
|
|
@@ -84,6 +95,7 @@ async function initCommand(options) {
|
|
|
84
95
|
if (options.plugin) initOptions.plugin = true;
|
|
85
96
|
if (options.muPlugin) initOptions.muPlugin = true;
|
|
86
97
|
if (options.theme) initOptions.theme = true;
|
|
98
|
+
if (options.sandbox) initOptions.sandbox = true;
|
|
87
99
|
|
|
88
100
|
const configPath = initConfig(projectPath, initOptions);
|
|
89
101
|
console.log(chalk.green(`β
Created configuration file: ${configPath}\n`));
|
|
@@ -101,11 +113,26 @@ async function initCommand(options) {
|
|
|
101
113
|
console.log(chalk.cyan(`βΉοΈ Detected project type: ${detectedType}\n`));
|
|
102
114
|
}
|
|
103
115
|
|
|
104
|
-
//
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
116
|
+
// Define project type choices
|
|
117
|
+
const projectTypeChoices = [
|
|
118
|
+
{ title: 'Plugin', value: 'plugin', description: 'WordPress plugin development' },
|
|
119
|
+
{ title: 'MU Plugin', value: 'mu-plugin', description: 'Must-use plugin development' },
|
|
120
|
+
{ title: 'Theme', value: 'theme', description: 'WordPress theme development' },
|
|
121
|
+
{ title: 'Sandbox', value: 'sandbox', description: 'Base WordPress environment (add code mappings later)' }
|
|
122
|
+
];
|
|
123
|
+
|
|
124
|
+
// Determine default project type with priority: CLI flag > detected type > default
|
|
125
|
+
const typeFromFlag = options.plugin ? 'plugin'
|
|
126
|
+
: options.muPlugin ? 'mu-plugin'
|
|
127
|
+
: options.theme ? 'theme'
|
|
128
|
+
: options.sandbox ? 'sandbox'
|
|
129
|
+
: null;
|
|
130
|
+
|
|
131
|
+
const preferredType = typeFromFlag || detectedType || 'plugin';
|
|
132
|
+
|
|
133
|
+
const defaultTypeIndex = projectTypeChoices.findIndex(
|
|
134
|
+
choice => choice.value === preferredType
|
|
135
|
+
);
|
|
109
136
|
|
|
110
137
|
const questions = [
|
|
111
138
|
{
|
|
@@ -119,13 +146,7 @@ async function initCommand(options) {
|
|
|
119
146
|
type: 'select',
|
|
120
147
|
name: 'projectType',
|
|
121
148
|
message: 'Project type',
|
|
122
|
-
choices:
|
|
123
|
-
{ title: 'Plugin', value: 'plugin', description: 'WordPress plugin development' },
|
|
124
|
-
{ title: 'MU Plugin', value: 'mu-plugin', description: 'Must-use plugin development' },
|
|
125
|
-
{ title: 'Theme', value: 'theme', description: 'WordPress theme development' },
|
|
126
|
-
{ title: 'Sandbox', value: 'sandbox', description: 'Base WordPress environment (add code mappings later)' },
|
|
127
|
-
{ title: 'Custom', value: 'custom', description: 'Custom mapping configuration' }
|
|
128
|
-
],
|
|
149
|
+
choices: projectTypeChoices,
|
|
129
150
|
initial: defaultTypeIndex
|
|
130
151
|
},
|
|
131
152
|
{
|
|
@@ -245,31 +266,12 @@ async function initCommand(options) {
|
|
|
245
266
|
}
|
|
246
267
|
};
|
|
247
268
|
|
|
248
|
-
// Add mapping based on project type
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
local: './',
|
|
252
|
-
container: `/var/www/html/wp-content/plugins/${answers.projectName}`
|
|
253
|
-
});
|
|
254
|
-
} else if (answers.projectType === 'mu-plugin') {
|
|
255
|
-
config.mappings.push({
|
|
256
|
-
local: './',
|
|
257
|
-
container: `/var/www/html/wp-content/mu-plugins/${answers.projectName}`
|
|
258
|
-
});
|
|
259
|
-
} else if (answers.projectType === 'theme') {
|
|
260
|
-
config.mappings.push({
|
|
261
|
-
local: './',
|
|
262
|
-
container: `/var/www/html/wp-content/themes/${answers.projectName}`
|
|
263
|
-
});
|
|
264
|
-
} else if (answers.projectType === 'sandbox') {
|
|
265
|
-
// Sandbox type: no initial mappings
|
|
266
|
-
// User can add mappings manually to config.mappings array
|
|
267
|
-
} else {
|
|
268
|
-
// Custom type
|
|
269
|
+
// Add mapping based on project type using template
|
|
270
|
+
const template = MAPPING_TEMPLATES[answers.projectType];
|
|
271
|
+
if (template) {
|
|
269
272
|
config.mappings.push({
|
|
270
273
|
local: './',
|
|
271
|
-
container: '
|
|
272
|
-
comment: 'Customize this mapping for your project'
|
|
274
|
+
container: template.replace('{name}', answers.projectName)
|
|
273
275
|
});
|
|
274
276
|
}
|
|
275
277
|
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Update command - Updates Docker images and recreates containers
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { execSync } from 'child_process';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import { loadConfig, loadKeychainCredentials, createSecureTempEnvFile, secureDeleteTempEnvFile, ENV_FILE_NAME } from '../config.js';
|
|
10
|
+
|
|
11
|
+
async function updateCommand(options = {}) {
|
|
12
|
+
console.log(chalk.blue('π Updating Docker images...\n'));
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
const projectPath = process.cwd();
|
|
16
|
+
const composePath = path.join(projectPath, '.buwp-local', 'docker-compose.yml');
|
|
17
|
+
const composeDir = path.dirname(composePath);
|
|
18
|
+
const envFilePath = path.join(projectPath, ENV_FILE_NAME);
|
|
19
|
+
|
|
20
|
+
// Check if docker-compose.yml exists
|
|
21
|
+
if (!fs.existsSync(composePath)) {
|
|
22
|
+
console.log(chalk.yellow('β οΈ No environment found.'));
|
|
23
|
+
console.log(chalk.gray('Run "buwp-local start" to create an environment.\n'));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Load config to get project name
|
|
28
|
+
const config = loadConfig(projectPath);
|
|
29
|
+
const projectName = config.projectName || 'buwp-local';
|
|
30
|
+
|
|
31
|
+
// Check if Docker is running
|
|
32
|
+
try {
|
|
33
|
+
execSync('docker info', { stdio: 'ignore' });
|
|
34
|
+
} catch (err) {
|
|
35
|
+
console.error(chalk.red('β Docker is not running'));
|
|
36
|
+
console.log(chalk.gray('Please start Docker Desktop and try again.\n'));
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Determine which services to pull
|
|
41
|
+
const pullAll = options.all || false;
|
|
42
|
+
const imageFilter = pullAll ? '' : 'wordpress';
|
|
43
|
+
|
|
44
|
+
// Step 1: Pull images (WordPress only by default, or all with --all flag)
|
|
45
|
+
console.log(chalk.cyan(pullAll ? 'π₯ Pulling all Docker images...' : 'π₯ Pulling WordPress image...'));
|
|
46
|
+
try {
|
|
47
|
+
execSync(
|
|
48
|
+
`docker compose -p ${projectName} -f "${composePath}" pull ${imageFilter}`,
|
|
49
|
+
{
|
|
50
|
+
cwd: composeDir,
|
|
51
|
+
stdio: 'inherit'
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
} catch (err) {
|
|
55
|
+
console.error(chalk.red('\nβ Failed to pull Docker images'));
|
|
56
|
+
console.log(chalk.gray('Check your Docker registry credentials and network connection.\n'));
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Step 2: Recreate containers with new images (preserves volumes)
|
|
61
|
+
// Need to pass environment variables just like start command does
|
|
62
|
+
console.log(chalk.cyan('\nπ¨ Recreating containers with new images...'));
|
|
63
|
+
|
|
64
|
+
// Load keychain credentials and create secure temp env file if available
|
|
65
|
+
let tempEnvPath = null;
|
|
66
|
+
const finalKeychainCredentials = loadKeychainCredentials();
|
|
67
|
+
const keychainCredCount = Object.keys(finalKeychainCredentials).length;
|
|
68
|
+
|
|
69
|
+
if (keychainCredCount > 0) {
|
|
70
|
+
try {
|
|
71
|
+
tempEnvPath = createSecureTempEnvFile(finalKeychainCredentials, projectName);
|
|
72
|
+
} catch (err) {
|
|
73
|
+
console.warn(chalk.yellow(`β οΈ Could not load keychain credentials: ${err.message}`));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Build env-file flags
|
|
78
|
+
const envFileFlag = fs.existsSync(envFilePath) ? `--env-file ${envFilePath}` : '';
|
|
79
|
+
const tempEnvFileFlag = tempEnvPath ? `--env-file ${tempEnvPath}` : '';
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
execSync(
|
|
83
|
+
`docker compose -p ${projectName} ${tempEnvFileFlag} ${envFileFlag} -f "${composePath}" up -d --force-recreate`,
|
|
84
|
+
{
|
|
85
|
+
cwd: composeDir,
|
|
86
|
+
stdio: 'inherit'
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
} catch (err) {
|
|
90
|
+
console.error(chalk.red('\nβ Failed to recreate containers'));
|
|
91
|
+
process.exit(1);
|
|
92
|
+
} finally {
|
|
93
|
+
// Always clean up temp env file
|
|
94
|
+
if (tempEnvPath) {
|
|
95
|
+
secureDeleteTempEnvFile(tempEnvPath);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Success message
|
|
100
|
+
console.log(chalk.green('\nβ
Update complete!\n'));
|
|
101
|
+
console.log(chalk.gray('Preserved:'));
|
|
102
|
+
console.log(chalk.gray(' β Database and WordPress data'));
|
|
103
|
+
console.log(chalk.gray(' β Volume mappings and configuration\n'));
|
|
104
|
+
console.log(chalk.cyan('Access your site at:'));
|
|
105
|
+
console.log(chalk.white(` https://${config.hostname}\n`));
|
|
106
|
+
|
|
107
|
+
} catch (err) {
|
|
108
|
+
console.error(chalk.red('\nβ Error:'), err.message);
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export default updateCommand;
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bostonuniversity/buwp-local",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Local WordPress development environment for Boston University projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"bin": {
|
|
8
|
-
"buwp-local": "
|
|
8
|
+
"buwp-local": "bin/buwp-local.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"test": "echo \"Error: no test specified\" && exit 1",
|
package/readme.md
CHANGED
|
@@ -99,7 +99,10 @@ Your local WordPress site should now be accessible at the hostname you configure
|
|
|
99
99
|
|
|
100
100
|
- π [Getting Started Guide](docs/GETTING_STARTED.md)
|
|
101
101
|
- π [Command Reference](docs/COMMANDS.md)
|
|
102
|
+
- πΊοΈ [Volume Mapping Patterns](docs/VOLUME_MAPPINGS.md) - Flexible development workflows
|
|
103
|
+
- π [Xdebug Setup](docs/XDEBUG.md) - Step debugging configuration
|
|
102
104
|
- π [Credential Management](docs/CREDENTIALS.md)
|
|
105
|
+
- π [Migration from VM Sandboxes](docs/MIGRATION_FROM_VM.md)
|
|
103
106
|
- ποΈ [Architecture](docs/ARCHITECTURE.md) (for contributors)
|
|
104
107
|
|
|
105
108
|
## Features
|