@bostonuniversity/buwp-local 0.5.3 → 0.6.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/ROADMAP.md +2 -1
- package/docs/ARCHITECTURE.md +691 -0
- package/docs/CHANGELOG.md +149 -0
- package/docs/COMMANDS.md +462 -0
- package/docs/CREDENTIALS.md +484 -0
- package/docs/GETTING_STARTED.md +234 -0
- package/docs/MULTI_PROJECT.md +513 -0
- package/docs/ROADMAP.md +247 -0
- package/lib/commands/init.js +2 -1
- package/lib/commands/keychain.js +1 -1
- package/lib/commands/start.js +193 -8
- package/package.json +1 -1
- package/readme.md +17 -0
- /package/{IMPLEMENTATION_NOTES_V0.5.0_PHASE3.md → docs/archive/IMPLEMENTATION_NOTES_V0.5.0_PHASE3.md} +0 -0
- /package/{IMPLEMENTATION_SUMMARY.md → docs/archive/IMPLEMENTATION_SUMMARY.md} +0 -0
- /package/{KEYCHAIN_IMPLEMENTATION.md → docs/archive/KEYCHAIN_IMPLEMENTATION.md} +0 -0
- /package/{macos-keychain-notes.md → docs/archive/macos-keychain-notes.md} +0 -0
package/docs/ROADMAP.md
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# Roadmap
|
|
2
|
+
|
|
3
|
+
Strategic direction and development priorities for buwp-local.
|
|
4
|
+
|
|
5
|
+
## Release History
|
|
6
|
+
|
|
7
|
+
### ✅ v0.5.x - Keychain & Credential Management (Complete)
|
|
8
|
+
|
|
9
|
+
**Status:** Shipped
|
|
10
|
+
|
|
11
|
+
**Key Features:**
|
|
12
|
+
- macOS Keychain integration for secure credential storage
|
|
13
|
+
- Automatic hex decoding for legacy multiline credentials
|
|
14
|
+
- Credential validation on startup with interactive setup
|
|
15
|
+
- Multi-project support with isolated Docker volumes
|
|
16
|
+
- Smart initialization for plugins, themes, and mu-plugins
|
|
17
|
+
|
|
18
|
+
**Result:** Ready for production use by small development teams.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Current Phase: v0.6.0 - Quality & Robustness
|
|
23
|
+
**Status:** Shipped
|
|
24
|
+
|
|
25
|
+
**Status:** In Progress
|
|
26
|
+
**Target Date:** December 2024
|
|
27
|
+
**Focus:** Foundation improvements before team rollout
|
|
28
|
+
|
|
29
|
+
### Features in Development
|
|
30
|
+
|
|
31
|
+
1. **Credential Validation** ✅ (Complete)
|
|
32
|
+
- Validates credentials before starting containers
|
|
33
|
+
- Offers interactive setup if credentials missing
|
|
34
|
+
- Clear error messages and guidance
|
|
35
|
+
|
|
36
|
+
2. **Documentation Consolidation** ✅ (Complete)
|
|
37
|
+
- Reorganized docs in `/docs` directory
|
|
38
|
+
- Comprehensive guides for all user levels
|
|
39
|
+
- Architecture documentation for contributors
|
|
40
|
+
|
|
41
|
+
3. **Robust /etc/hosts Detection** ✅ (Complete)
|
|
42
|
+
- Detects if hostname exists in `/etc/hosts` during start
|
|
43
|
+
- Provides copy-paste sudo command if missing
|
|
44
|
+
- Smart messaging (only shows once per project)
|
|
45
|
+
- Non-blocking (user can continue without adding)
|
|
46
|
+
|
|
47
|
+
### Success Criteria
|
|
48
|
+
- ✅ Zero setup confusion for new users
|
|
49
|
+
- ✅ All common workflows documented
|
|
50
|
+
- ✅ Hostname setup guidance clear and actionable
|
|
51
|
+
|
|
52
|
+
**Status:** All v0.6.0 features complete. Ready for initial user rollout.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Lessons Learned: /etc/hosts Management
|
|
57
|
+
|
|
58
|
+
### What We Built (v0.6.0)
|
|
59
|
+
The detection-only approach proved to be the right choice:
|
|
60
|
+
- **Non-intrusive** - Checks once, shows clear instructions
|
|
61
|
+
- **No sudo required** - Detection runs without elevated permissions
|
|
62
|
+
- **Smart persistence** - Doesn't nag on every start
|
|
63
|
+
- **User control** - Provides copy-paste command, user decides when to run
|
|
64
|
+
|
|
65
|
+
### Future Consideration: Automatic Management
|
|
66
|
+
|
|
67
|
+
**Library Identified:** [`hostile`](https://www.npmjs.com/package/hostile) npm package
|
|
68
|
+
- ~500k weekly downloads, well-maintained
|
|
69
|
+
- Cross-platform (macOS, Linux, Windows)
|
|
70
|
+
- Programmatic API: `hostile.set('127.0.0.1', 'hostname')`
|
|
71
|
+
- Sync and async methods available
|
|
72
|
+
|
|
73
|
+
**Why We're Not Implementing It Now:**
|
|
74
|
+
|
|
75
|
+
1. **Requires sudo** - Password prompt interrupts smooth startup flow
|
|
76
|
+
2. **Security sensitivity** - Modifying system files needs user trust
|
|
77
|
+
3. **Current solution works** - Detection + copy-paste is clear and effective
|
|
78
|
+
4. **Premature optimization** - Need real user feedback first
|
|
79
|
+
|
|
80
|
+
**If We Revisit (v0.8.0+):**
|
|
81
|
+
|
|
82
|
+
Implementation would be straightforward:
|
|
83
|
+
```javascript
|
|
84
|
+
import hostile from 'hostile';
|
|
85
|
+
|
|
86
|
+
// Add hostname (requires sudo, prompts for password)
|
|
87
|
+
hostile.set('127.0.0.1', config.hostname, (err) => {
|
|
88
|
+
if (err) {
|
|
89
|
+
// Fall back to manual instructions
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Remove on destroy
|
|
94
|
+
hostile.remove('127.0.0.1', config.hostname);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Decision criteria for future:**
|
|
98
|
+
- Do >50% of users request automatic management?
|
|
99
|
+
- Is sudo prompt acceptable to most users?
|
|
100
|
+
- Would opt-in flag (`autoManageHosts: true`) address concerns?
|
|
101
|
+
- Does it meaningfully improve onboarding over current approach?
|
|
102
|
+
|
|
103
|
+
**Current recommendation:** Gather feedback from Stage 1 users (2-3 developers) in December 2024. If hostname setup proves to be a friction point, revisit automatic management in Q1 2025.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Next Phase: v0.7.0 - Developer Experience
|
|
108
|
+
|
|
109
|
+
**Status:** Planned
|
|
110
|
+
**Timeline:** January 2025 (after team onboarding feedback)
|
|
111
|
+
**Focus:** Ease of use and visibility
|
|
112
|
+
|
|
113
|
+
### Potential Features
|
|
114
|
+
|
|
115
|
+
- **Xdebug Integration**
|
|
116
|
+
- Enable Xdebug in containers
|
|
117
|
+
- Documentation for IDE setup
|
|
118
|
+
- Configuration options in `.buwp-local.json`
|
|
119
|
+
|
|
120
|
+
- **Security Checks**
|
|
121
|
+
- Check database access on db port (e.g. `localhost:3306`)
|
|
122
|
+
- Consider more stringent default database passwords
|
|
123
|
+
|
|
124
|
+
- **Improved Windows and Linux support**
|
|
125
|
+
- Multiplatform /etc/hosts hostname management
|
|
126
|
+
- Evaluate credential storage solutions for non-macOS platforms
|
|
127
|
+
|
|
128
|
+
- **Project Status & Listing**
|
|
129
|
+
- View all running projects: `buwp-local list`
|
|
130
|
+
- Quick status checks: `buwp-local status`
|
|
131
|
+
|
|
132
|
+
- **Health Checks**
|
|
133
|
+
- Verify services are running properly
|
|
134
|
+
- Database connectivity validation
|
|
135
|
+
- Clear diagnostics on failures
|
|
136
|
+
|
|
137
|
+
- **Improved Error Messages**
|
|
138
|
+
- Docker startup failures → actionable solutions
|
|
139
|
+
- Credential issues → clear next steps
|
|
140
|
+
- Port conflicts → suggest alternatives
|
|
141
|
+
|
|
142
|
+
### Prioritization
|
|
143
|
+
Will be informed by feedback from initial 2-3 users and actual pain points observed during rollout.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Future Phases: v0.8.0+
|
|
148
|
+
|
|
149
|
+
**Status:** Conceptual
|
|
150
|
+
**Timeline:** TBD based on team feedback
|
|
151
|
+
|
|
152
|
+
### Potential Features (Lower Priority)
|
|
153
|
+
|
|
154
|
+
- **SSL Certificate Generation** - Local HTTPS with mkcert
|
|
155
|
+
- **Database Backup/Restore** - Simplified snapshots and recovery
|
|
156
|
+
- **Performance Monitoring** - Real-time resource usage tracking
|
|
157
|
+
- **Team Configuration Sync** - Share project configurations across team
|
|
158
|
+
- **Cross-Platform Support** - Windows WSL2 and Linux credential storage
|
|
159
|
+
|
|
160
|
+
**Note:** Automatic `/etc/hosts` management deferred pending user feedback. See "Lessons Learned" section above for details on the `hostile` library approach.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Roadmap by User Stage
|
|
165
|
+
|
|
166
|
+
### Stage 1: Initial Users (Now)
|
|
167
|
+
**Users:** 1-3 developers
|
|
168
|
+
**Goal:** Validate core functionality
|
|
169
|
+
**Release:** v0.6.0
|
|
170
|
+
**Focus:** Robustness, clear setup, good documentation
|
|
171
|
+
|
|
172
|
+
### Stage 2: Team Rollout (Q1 2025)
|
|
173
|
+
**Users:** 10-15 developers
|
|
174
|
+
**Goal:** Find and fix real-world issues
|
|
175
|
+
**Release:** v0.7.0+
|
|
176
|
+
**Focus:** Developer experience, error handling
|
|
177
|
+
|
|
178
|
+
### Stage 3: Broader Adoption (Q2 2025+)
|
|
179
|
+
**Users:** 20+ developers
|
|
180
|
+
**Goal:** Self-service onboarding
|
|
181
|
+
**Release:** v1.0.0+
|
|
182
|
+
**Focus:** Advanced features, automation
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Technical Debt
|
|
187
|
+
|
|
188
|
+
### Testing
|
|
189
|
+
- Unit tests for core modules (config, keychain, docker-compose)
|
|
190
|
+
- Integration tests for Docker operations
|
|
191
|
+
- E2E tests for full workflows
|
|
192
|
+
|
|
193
|
+
### Documentation
|
|
194
|
+
- Troubleshooting guide for common issues
|
|
195
|
+
- FAQ section
|
|
196
|
+
- Video tutorials for setup
|
|
197
|
+
|
|
198
|
+
### Quality
|
|
199
|
+
- Standardized error handling across commands
|
|
200
|
+
- Centralized logging system
|
|
201
|
+
- Better validation for edge cases
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Decision Framework
|
|
206
|
+
|
|
207
|
+
Features will be prioritized based on:
|
|
208
|
+
|
|
209
|
+
1. **User Feedback** - What's actually blocking users?
|
|
210
|
+
2. **Adoption Impact** - Does it help onboard new users?
|
|
211
|
+
3. **Implementation Effort** - Can it be done quickly?
|
|
212
|
+
4. **Maintenance Burden** - Will it create ongoing support overhead?
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## How to Use This Roadmap
|
|
217
|
+
|
|
218
|
+
**For Users:**
|
|
219
|
+
- See what's coming and when
|
|
220
|
+
- Understand current release focus
|
|
221
|
+
- Provide feedback on priorities
|
|
222
|
+
|
|
223
|
+
**For Contributors:**
|
|
224
|
+
- Clear phases and timeline
|
|
225
|
+
- See future enhancement opportunities
|
|
226
|
+
- Link to technical details in [ARCHITECTURE.md](ARCHITECTURE.md)
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Technical Details
|
|
231
|
+
|
|
232
|
+
For detailed information about planned features, implementation approaches, and architecture decisions, see:
|
|
233
|
+
|
|
234
|
+
- **[ARCHITECTURE.md](ARCHITECTURE.md)** - Planned Features section
|
|
235
|
+
- **[CHANGELOG.md](CHANGELOG.md)** - Version history and release notes
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Feedback
|
|
240
|
+
|
|
241
|
+
Have ideas for the roadmap? Questions about priorities?
|
|
242
|
+
|
|
243
|
+
- **Early users:** Direct feedback via chat/email
|
|
244
|
+
- **GitHub issues:** Feature requests and suggestions
|
|
245
|
+
- **Team meetings:** Quarterly roadmap reviews
|
|
246
|
+
|
|
247
|
+
Current focus: Getting v0.6.0 stable and ready for initial rollout to 2-3 users. 🚀
|
package/lib/commands/init.js
CHANGED
|
@@ -295,7 +295,8 @@ async function initCommand(options) {
|
|
|
295
295
|
// Show next steps
|
|
296
296
|
console.log(chalk.cyan('📝 Next steps:'));
|
|
297
297
|
console.log(chalk.gray(' 1. Check keychain credentials or add .env.local with your credentials'));
|
|
298
|
-
console.log(chalk.gray(
|
|
298
|
+
console.log(chalk.gray(' 2. Add to /etc/hosts with this command:'));
|
|
299
|
+
console.log(chalk.cyan(` echo "127.0.0.1 ${answers.hostname}" | sudo tee -a /etc/hosts\n`));
|
|
299
300
|
|
|
300
301
|
if (answers.projectType === 'sandbox') {
|
|
301
302
|
console.log(chalk.gray(' 3. Edit .buwp-local.json and add volume mappings to the mappings array'));
|
package/lib/commands/keychain.js
CHANGED
|
@@ -635,7 +635,7 @@ function showHelp() {
|
|
|
635
635
|
console.log(' # Interactive setup (prompts for each credential)');
|
|
636
636
|
console.log(' buwp-local keychain setup\n');
|
|
637
637
|
console.log(' # Bulk import from JSON file');
|
|
638
|
-
console.log(' buwp-local keychain setup --file
|
|
638
|
+
console.log(' buwp-local keychain setup --file buwp-local-credentials.json\n');
|
|
639
639
|
console.log(' # Interactive prompt for single-line credential');
|
|
640
640
|
console.log(' buwp-local keychain set WORDPRESS_DB_PASSWORD\n');
|
|
641
641
|
console.log(' # Set single-line credential directly');
|
package/lib/commands/start.js
CHANGED
|
@@ -6,8 +6,136 @@ import chalk from 'chalk';
|
|
|
6
6
|
import { execSync } from 'child_process';
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import fs from 'fs';
|
|
9
|
+
import prompts from 'prompts';
|
|
9
10
|
import { loadConfig, validateConfig, ENV_FILE_NAME, loadKeychainCredentials, createSecureTempEnvFile, secureDeleteTempEnvFile } from '../config.js';
|
|
10
11
|
import { generateComposeFile } from '../compose-generator.js';
|
|
12
|
+
import keychainCommand from './keychain.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Required credentials that must be present for WordPress to function
|
|
16
|
+
*/
|
|
17
|
+
const REQUIRED_CREDENTIALS = [
|
|
18
|
+
'WORDPRESS_DB_PASSWORD',
|
|
19
|
+
'DB_ROOT_PASSWORD'
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Check if hostname exists in /etc/hosts
|
|
24
|
+
* @param {string} hostname - Hostname to check
|
|
25
|
+
* @returns {object} { found: boolean, error?: string }
|
|
26
|
+
*/
|
|
27
|
+
function checkHostsFile(hostname) {
|
|
28
|
+
try {
|
|
29
|
+
const hostsPath = '/etc/hosts';
|
|
30
|
+
const content = fs.readFileSync(hostsPath, 'utf8');
|
|
31
|
+
const lines = content.split('\n');
|
|
32
|
+
|
|
33
|
+
// Check each line for hostname
|
|
34
|
+
for (const line of lines) {
|
|
35
|
+
// Skip comments and empty lines
|
|
36
|
+
if (line.trim().startsWith('#') || !line.trim()) continue;
|
|
37
|
+
|
|
38
|
+
// Parse: "127.0.0.1 hostname.local" or "127.0.0.1\thostname.local"
|
|
39
|
+
const parts = line.trim().split(/\s+/);
|
|
40
|
+
if (parts.length >= 2) {
|
|
41
|
+
// Check if hostname appears in any position after IP
|
|
42
|
+
const hostnames = parts.slice(1);
|
|
43
|
+
if (hostnames.includes(hostname)) {
|
|
44
|
+
return { found: true };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return { found: false };
|
|
50
|
+
} catch (error) {
|
|
51
|
+
// /etc/hosts not readable (unlikely on macOS)
|
|
52
|
+
return { found: false, error: error.message };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Check if we've already shown the hosts warning for this project
|
|
58
|
+
* @param {string} projectPath - Project directory path
|
|
59
|
+
* @returns {boolean} true if warning already shown
|
|
60
|
+
*/
|
|
61
|
+
function hasShownHostsWarning(projectPath) {
|
|
62
|
+
const warningFile = path.join(projectPath, '.buwp-local', '.hosts-warning-shown');
|
|
63
|
+
return fs.existsSync(warningFile);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Mark that we've shown the hosts warning for this project
|
|
68
|
+
* @param {string} projectPath - Project directory path
|
|
69
|
+
*/
|
|
70
|
+
function markHostsWarningShown(projectPath) {
|
|
71
|
+
const dir = path.join(projectPath, '.buwp-local');
|
|
72
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
73
|
+
const warningFile = path.join(dir, '.hosts-warning-shown');
|
|
74
|
+
fs.writeFileSync(warningFile, Date.now().toString());
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Check if required credentials are available in keychain or .env.local
|
|
79
|
+
* @param {object} keychainCreds - Credentials loaded from keychain
|
|
80
|
+
* @param {string} envFilePath - Path to .env.local file
|
|
81
|
+
* @returns {object} { isValid, missing }
|
|
82
|
+
*/
|
|
83
|
+
function validateCredentials(keychainCreds, envFilePath) {
|
|
84
|
+
const missing = [];
|
|
85
|
+
|
|
86
|
+
for (const key of REQUIRED_CREDENTIALS) {
|
|
87
|
+
// Check if credential exists in keychain
|
|
88
|
+
if (keychainCreds[key]) {
|
|
89
|
+
continue; // Found in keychain
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Check if credential exists in .env.local
|
|
93
|
+
if (fs.existsSync(envFilePath)) {
|
|
94
|
+
const envContent = fs.readFileSync(envFilePath, 'utf8');
|
|
95
|
+
if (envContent.includes(`${key}=`)) {
|
|
96
|
+
continue; // Found in .env.local
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Credential not found anywhere
|
|
101
|
+
missing.push(key);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
isValid: missing.length === 0,
|
|
106
|
+
missing
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Prompt user to set up missing credentials
|
|
112
|
+
* @param {string[]} missingCreds - List of missing credential keys
|
|
113
|
+
* @returns {Promise<boolean>} true if user wants to set up, false otherwise
|
|
114
|
+
*/
|
|
115
|
+
async function promptCredentialSetup(missingCreds) {
|
|
116
|
+
console.log(chalk.yellow('\n⚠️ Missing Required Credentials\n'));
|
|
117
|
+
console.log(chalk.gray('The following credentials are not configured:\n'));
|
|
118
|
+
missingCreds.forEach(key => {
|
|
119
|
+
console.log(chalk.gray(` - ${key}`));
|
|
120
|
+
});
|
|
121
|
+
console.log('');
|
|
122
|
+
|
|
123
|
+
console.log(chalk.cyan('You can set up credentials in two ways:\n'));
|
|
124
|
+
console.log(chalk.white(' 1. Use macOS Keychain (recommended):'));
|
|
125
|
+
console.log(chalk.gray(' npx buwp-local keychain setup\n'));
|
|
126
|
+
console.log(chalk.white(' 2. Create .env.local file in your project:'));
|
|
127
|
+
console.log(chalk.gray(' cp .env.local.example .env.local'));
|
|
128
|
+
console.log(chalk.gray(' # Edit .env.local with your credentials\n'));
|
|
129
|
+
|
|
130
|
+
const { shouldSetup } = await prompts({
|
|
131
|
+
type: 'confirm',
|
|
132
|
+
name: 'shouldSetup',
|
|
133
|
+
message: 'Would you like to set up credentials now using Keychain?',
|
|
134
|
+
initial: true
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
return shouldSetup;
|
|
138
|
+
}
|
|
11
139
|
|
|
12
140
|
async function startCommand(options) {
|
|
13
141
|
console.log(chalk.blue('🚀 Starting BU WordPress local environment...\n'));
|
|
@@ -43,6 +171,68 @@ async function startCommand(options) {
|
|
|
43
171
|
process.exit(1);
|
|
44
172
|
}
|
|
45
173
|
|
|
174
|
+
// Load and validate credentials early
|
|
175
|
+
const envFilePath = path.join(projectPath, ENV_FILE_NAME);
|
|
176
|
+
const keychainCredentials = loadKeychainCredentials();
|
|
177
|
+
const credentialValidation = validateCredentials(keychainCredentials, envFilePath);
|
|
178
|
+
|
|
179
|
+
if (!credentialValidation.isValid) {
|
|
180
|
+
const shouldSetup = await promptCredentialSetup(credentialValidation.missing);
|
|
181
|
+
|
|
182
|
+
if (shouldSetup) {
|
|
183
|
+
// Run keychain setup command
|
|
184
|
+
console.log(chalk.gray('\nLaunching Keychain Setup...\n'));
|
|
185
|
+
await keychainCommand('setup', [], {});
|
|
186
|
+
|
|
187
|
+
// Reload credentials after setup
|
|
188
|
+
const reloadedCreds = loadKeychainCredentials();
|
|
189
|
+
const revalidation = validateCredentials(reloadedCreds, envFilePath);
|
|
190
|
+
|
|
191
|
+
if (!revalidation.isValid) {
|
|
192
|
+
console.log(chalk.red('\n❌ Setup incomplete. Required credentials still missing:\n'));
|
|
193
|
+
revalidation.missing.forEach(key => {
|
|
194
|
+
console.log(chalk.red(` - ${key}`));
|
|
195
|
+
});
|
|
196
|
+
console.log(chalk.gray('\nPlease complete setup or add credentials to .env.local\n'));
|
|
197
|
+
process.exit(1);
|
|
198
|
+
}
|
|
199
|
+
} else {
|
|
200
|
+
console.log(chalk.red('\n❌ Cannot start without required credentials.\n'));
|
|
201
|
+
process.exit(1);
|
|
202
|
+
}
|
|
203
|
+
} else {
|
|
204
|
+
console.log(chalk.green('✓ Required credentials validated\n'));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Check /etc/hosts for hostname entry
|
|
208
|
+
if (!hasShownHostsWarning(projectPath)) {
|
|
209
|
+
const hostsCheck = checkHostsFile(config.hostname);
|
|
210
|
+
|
|
211
|
+
if (!hostsCheck.found) {
|
|
212
|
+
console.log(chalk.yellow('⚠️ Hostname not found in /etc/hosts\n'));
|
|
213
|
+
console.log(`Your site won't be accessible at ${chalk.cyan(`http://${config.hostname}`)}`);
|
|
214
|
+
console.log('until you add this entry:\n');
|
|
215
|
+
console.log(chalk.green(` 127.0.0.1 ${config.hostname}\n`));
|
|
216
|
+
console.log('Run this command to add it (copy and paste, and then enter your password):\n');
|
|
217
|
+
console.log(chalk.cyan(` echo "127.0.0.1 ${config.hostname}" | sudo tee -a /etc/hosts\n`));
|
|
218
|
+
|
|
219
|
+
const { continueStart } = await prompts({
|
|
220
|
+
type: 'confirm',
|
|
221
|
+
name: 'continueStart',
|
|
222
|
+
message: 'Continue starting containers?',
|
|
223
|
+
initial: true
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
if (!continueStart) {
|
|
227
|
+
console.log(chalk.gray('\nStart cancelled. Add hostname to /etc/hosts and try again.'));
|
|
228
|
+
process.exit(0);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Mark warning as shown so we don't annoy user on every start
|
|
232
|
+
markHostsWarningShown(projectPath);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
46
236
|
// Generate docker-compose.yml
|
|
47
237
|
console.log(chalk.gray('Generating docker-compose.yml...'));
|
|
48
238
|
const composePath = generateComposeFile(config, projectPath);
|
|
@@ -63,12 +253,12 @@ async function startCommand(options) {
|
|
|
63
253
|
|
|
64
254
|
// Load keychain credentials and create secure temp env file if available
|
|
65
255
|
let tempEnvPath = null;
|
|
66
|
-
const
|
|
67
|
-
const keychainCredCount = Object.keys(
|
|
256
|
+
const finalKeychainCredentials = loadKeychainCredentials();
|
|
257
|
+
const keychainCredCount = Object.keys(finalKeychainCredentials).length;
|
|
68
258
|
|
|
69
259
|
if (keychainCredCount > 0) {
|
|
70
260
|
try {
|
|
71
|
-
tempEnvPath = createSecureTempEnvFile(
|
|
261
|
+
tempEnvPath = createSecureTempEnvFile(finalKeychainCredentials, projectName);
|
|
72
262
|
console.log(chalk.gray(`✓ Loaded ${keychainCredCount} credentials from keychain\n`));
|
|
73
263
|
} catch (err) {
|
|
74
264
|
console.warn(chalk.yellow(`⚠️ Could not load keychain credentials: ${err.message}`));
|
|
@@ -76,7 +266,6 @@ async function startCommand(options) {
|
|
|
76
266
|
}
|
|
77
267
|
|
|
78
268
|
// Check if .env.local exists and build env-file flags
|
|
79
|
-
const envFilePath = path.join(projectPath, ENV_FILE_NAME);
|
|
80
269
|
const envFileFlag = fs.existsSync(envFilePath) ? `--env-file ${envFilePath}` : '';
|
|
81
270
|
const tempEnvFileFlag = tempEnvPath ? `--env-file ${tempEnvPath}` : '';
|
|
82
271
|
|
|
@@ -111,10 +300,6 @@ async function startCommand(options) {
|
|
|
111
300
|
console.log(chalk.white(' buwp-local stop - Stop environment'));
|
|
112
301
|
console.log(chalk.white(' buwp-local destroy - Remove environment\n'));
|
|
113
302
|
|
|
114
|
-
// Reminder about /etc/hosts
|
|
115
|
-
console.log(chalk.yellow('⚠️ Remember to add this to your /etc/hosts file:'));
|
|
116
|
-
console.log(chalk.white(` 127.0.0.1 ${config.hostname}\n`));
|
|
117
|
-
|
|
118
303
|
} catch (err) {
|
|
119
304
|
console.error(chalk.red('\n❌ Error:'), err.message);
|
|
120
305
|
process.exit(1);
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
This repository contains resources and instructions for setting up a local WordPress development environment for Boston University projects. It uses the BU WordPress container image and provides the additional resources needed to run it locally with Docker.
|
|
4
4
|
|
|
5
|
+
The package can be installed in a specific repo for development of that one package, or standalone for more general use, mapping local code into the container as needed.
|
|
5
6
|
|
|
6
7
|
## Quickstart for plugin or theme development
|
|
7
8
|
|
|
@@ -84,3 +85,19 @@ Your local WordPress site should now be accessible at the hostname you configure
|
|
|
84
85
|
```
|
|
85
86
|
|
|
86
87
|
This will download the latest snapshot from the specified source and import it into your local WordPress environment.
|
|
88
|
+
|
|
89
|
+
## Documentation
|
|
90
|
+
|
|
91
|
+
- 📘 [Getting Started Guide](docs/GETTING_STARTED.md)
|
|
92
|
+
- 📖 [Command Reference](docs/COMMANDS.md)
|
|
93
|
+
- 🔐 [Credential Management](docs/CREDENTIALS.md)
|
|
94
|
+
- 🏗️ [Architecture](docs/ARCHITECTURE.md) (for contributors)
|
|
95
|
+
|
|
96
|
+
## Features
|
|
97
|
+
|
|
98
|
+
- ✅ One-time credential setup with macOS Keychain
|
|
99
|
+
- ✅ Isolated environments for multiple projects
|
|
100
|
+
- ✅ Pre-configured BU infrastructure (Shibboleth, S3, Redis)
|
|
101
|
+
- ✅ Smart initialization for plugins, themes, and mu-plugins
|
|
102
|
+
- ✅ Volume mapping for live code sync
|
|
103
|
+
- ✅ Xdebug support for step debugging
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|