Skip to content

Commit 5e0220b

Browse files
committed
added CLAUDE.md
1 parent 7454ae5 commit 5e0220b

File tree

1 file changed

+316
-0
lines changed

1 file changed

+316
-0
lines changed

CLAUDE.md

Lines changed: 316 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
**Nette Bootstrap** is a foundational library for the Nette Framework that handles application initialization and Dependency Injection (DI) container generation. It's a standalone package (`nette/bootstrap`) that:
8+
9+
- Initializes application environment settings (debug mode, timezone, etc.)
10+
- Generates and manages the DI container
11+
- Loads and processes NEON configuration files
12+
- Integrates all Nette framework extensions
13+
- Provides fluent interface for application configuration
14+
15+
**Requirements:** PHP 8.0-8.5
16+
17+
## Basic Usage
18+
19+
Typical bootstrap sequence for standalone usage (outside of full Nette framework):
20+
21+
```php
22+
// 1. Create configurator
23+
$configurator = new Nette\Bootstrap\Configurator;
24+
25+
// 2. Set temp directory (required - for DI container cache)
26+
$configurator->setTempDirectory(__DIR__ . '/temp');
27+
28+
// 3. Load configuration files
29+
$configurator->addConfig(__DIR__ . '/database.neon');
30+
// Multiple configs can be added - later files override earlier ones
31+
$configurator->addConfig(__DIR__ . '/services.neon');
32+
33+
// 4. Optional: Add dynamic parameters (not cached, evaluated per request)
34+
$configurator->addDynamicParameters([
35+
'remoteIp' => $_SERVER['REMOTE_ADDR'],
36+
]);
37+
38+
// 5. Create DI container
39+
$container = $configurator->createContainer();
40+
41+
// 6. Get services from container
42+
$db = $container->getByType(Nette\Database\Connection::class);
43+
// or by name when multiple instances exist
44+
$db = $container->getByName('database.main.connection');
45+
```
46+
47+
**Important:** On Linux/macOS, set write permissions for the `temp/` directory.
48+
49+
### Development vs Production Mode
50+
51+
The container behavior differs between modes:
52+
53+
- **Development mode:** Container auto-updates when configuration files change (convenience)
54+
- **Production mode:** Container generated once, changes ignored (performance)
55+
56+
**Autodetection:**
57+
- Development: Running on localhost (`127.0.0.1` or `::1`) without proxy
58+
- Production: All other cases
59+
60+
**Manual control:**
61+
62+
```php
63+
// Enable for specific IP addresses
64+
$configurator->setDebugMode('23.75.345.200');
65+
// or array of IPs
66+
$configurator->setDebugMode(['23.75.345.200', '192.168.1.100']);
67+
68+
// Combine IP with cookie secret (recommended for production debugging)
69+
// Requires 'nette-debug' cookie with value 'secret1234'
70+
$configurator->setDebugMode('[email protected]');
71+
72+
// Force disable even for localhost
73+
$configurator->setDebugMode(false);
74+
```
75+
76+
### Retrieving Services from Container
77+
78+
```php
79+
// By type (when only one instance exists)
80+
$db = $container->getByType(Nette\Database\Connection::class);
81+
$explorer = $container->getByType(Nette\Database\Explorer::class);
82+
83+
// By name (when multiple instances exist)
84+
$mainDb = $container->getByName('database.main.connection');
85+
$logDb = $container->getByName('database.log.connection');
86+
```
87+
88+
## Essential Commands
89+
90+
### Testing
91+
92+
```bash
93+
# Run all tests
94+
vendor/bin/tester tests -s
95+
96+
# Run all tests with coverage info
97+
vendor/bin/tester tests -s -C
98+
99+
# Run specific test file
100+
vendor/bin/tester tests/Bootstrap/Configurator.basic.phpt
101+
102+
# Run tests with lowest dependencies (CI check)
103+
composer update --prefer-lowest && vendor/bin/tester tests -s
104+
```
105+
106+
### Code Quality
107+
108+
```bash
109+
# Run PHPStan static analysis
110+
composer phpstan
111+
112+
# Run PHPStan without progress bar (CI mode)
113+
composer phpstan -- --no-progress
114+
```
115+
116+
### Development
117+
118+
```bash
119+
# Install dependencies
120+
composer install
121+
122+
# Update dependencies
123+
composer update
124+
```
125+
126+
## Architecture
127+
128+
### Core Component: Configurator Class
129+
130+
Location: `src/Bootstrap/Configurator.php`
131+
132+
The `Configurator` class is the heart of this library. It follows a fluent interface pattern and handles:
133+
134+
**1. Environment Setup:**
135+
- `setDebugMode()` - Toggle debug/production mode with IP-based detection
136+
- `setTempDirectory()` - Set cache directory for DI container
137+
- `setTimeZone()` - Configure PHP timezone
138+
- `enableTracy()` - Enable Tracy debugger (if installed)
139+
140+
**2. Parameter Management:**
141+
- **Static parameters** (set at config time, cached): `addStaticParameters()`
142+
- **Dynamic parameters** (evaluated per request, not cached): `addDynamicParameters()`
143+
- Useful for runtime values like `$_SERVER['REMOTE_ADDR']`, current user, etc.
144+
- Referenced in config using `%parameterName%` notation
145+
146+
**Default parameters available:**
147+
- `appDir` - Application directory
148+
- `wwwDir` - Web root directory
149+
- `tempDir` - Temporary/cache directory
150+
- `vendorDir` - Composer vendor directory
151+
- `rootDir` - Project root (auto-detected from Composer)
152+
- `baseUrl` - Base URL (dynamically resolved from HTTP request)
153+
- `debugMode` / `productionMode` - Environment flags
154+
- `consoleMode` - CLI detection
155+
156+
**3. Configuration Loading:**
157+
- `addConfig(string|array)` - Load NEON files or inline arrays
158+
- Multiple configs are merged (later configs override earlier ones)
159+
- Parameter expansion with `%paramName%` syntax
160+
- Recursive parameter substitution with type coercion
161+
162+
**4. Container Generation:**
163+
- `createContainer()` - Create and initialize DI container
164+
- `loadContainer()` - Load cached container or generate new one
165+
- Caching based on: configs, static params, dynamic param names, PHP version, Composer mtime
166+
167+
### Default Extensions System
168+
169+
Bootstrap pre-registers 17 framework extensions in `$defaultExtensions`:
170+
171+
```
172+
application, assets, cache, constants, database, decorator, di,
173+
extensions, forms, http, inject, latte, mail, php, routing,
174+
search, security, session, tracy
175+
```
176+
177+
Each extension processes its own configuration section (e.g., `database:`, `forms:`, `mail:`).
178+
179+
### Custom Bootstrap Extensions
180+
181+
Two extensions in `src/Bootstrap/Extensions/`:
182+
183+
**ConstantsExtension** - Defines PHP constants from configuration:
184+
```neon
185+
constants:
186+
MY_CONST: value
187+
ANOTHER: %parameter%
188+
```
189+
190+
**PhpExtension** - Sets PHP ini directives:
191+
```neon
192+
php:
193+
date.timezone: Europe/Prague
194+
display_errors: "0"
195+
```
196+
197+
### Configuration Flow
198+
199+
```
200+
1. User creates Configurator and sets environment
201+
2. User adds config files via addConfig()
202+
3. Configurator loads all NEON configs
203+
4. Extensions are instantiated in order
204+
5. Each extension processes its config section
205+
6. DI Compiler generates PHP container class
206+
7. Container cached in tempDir/cache/nette.configurator/
207+
8. Dynamic parameters injected at runtime
208+
```
209+
210+
### Debug Mode Detection
211+
212+
`Configurator::detectDebugMode($list)` supports:
213+
- **IP whitelist matching** - Single IP or CIDR subnet (e.g., `'23.75.345.200'` or `['192.168.1.0/24']`)
214+
- **Cookie-based secret** - Format: `'secret@ip'` (e.g., `'[email protected]'`)
215+
- Checks for `nette-debug` cookie with the secret value
216+
- Recommended for production debugging - safe even if IP changes
217+
- **X-Forwarded-For** proxy header detection
218+
- **Auto-enables** for localhost (`127.0.0.1`, `::1`)
219+
- **Fallback** to computer hostname when no REMOTE_ADDR (CLI mode)
220+
221+
## Testing Infrastructure
222+
223+
**Framework:** Nette Tester with PHPT format (18 test files)
224+
225+
**Test Organization:**
226+
```
227+
tests/
228+
├── bootstrap.php # Test setup with getTempDir() helper
229+
├── Bootstrap/
230+
│ ├── Configurator.*.phpt
231+
│ ├── ConstantsExtension.phpt
232+
│ ├── PhpExtension.phpt
233+
│ └── files/ # NEON test fixtures
234+
└── tmp/ # Temporary test output
235+
```
236+
237+
**Test Bootstrap Helpers:**
238+
- `getTempDir()` - Creates per-process temp directory with automatic garbage collection
239+
- `test($title, $function)` - Simple test wrapper
240+
241+
**Test Pattern:**
242+
```php
243+
require __DIR__ . '/../bootstrap.php';
244+
245+
$configurator = new Configurator;
246+
$configurator->setTempDirectory(getTempDir());
247+
$configurator->addConfig('files/config.neon');
248+
$container = $configurator->createContainer();
249+
250+
Assert::same('expected', $container->parameters['foo']);
251+
```
252+
253+
## CI/CD
254+
255+
**GitHub Actions workflows:**
256+
257+
1. **Tests** (`.github/workflows/tests.yml`):
258+
- Matrix: PHP 8.0, 8.1, 8.2, 8.3, 8.4, 8.5
259+
- Runs `vendor/bin/tester tests -s -C`
260+
- Lowest dependencies test with `composer update --prefer-lowest`
261+
- Code coverage with phpdbg and php-coveralls
262+
263+
2. **Static Analysis** (`.github/workflows/static-analysis.yml`):
264+
- Runs on master branch (informative only)
265+
- Command: `composer phpstan -- --no-progress`
266+
- Continues on error
267+
268+
## NEON Configuration Format
269+
270+
Bootstrap uses NEON (Nette's configuration language). Key sections:
271+
272+
**Parameters:**
273+
```neon
274+
parameters:
275+
appDir: /path/to/app
276+
debugMode: true
277+
custom: value
278+
```
279+
280+
**Extensions:**
281+
```neon
282+
extensions:
283+
myExt: App\MyExtension
284+
```
285+
286+
**Framework-specific sections:**
287+
```neon
288+
constants:
289+
MY_CONST: value
290+
291+
php:
292+
date.timezone: Europe/Prague
293+
294+
database:
295+
dsn: "mysql:host=127.0.0.1;dbname=test"
296+
user: root
297+
password: secret
298+
```
299+
300+
**Parameter expansion** - Use `%paramName%` to reference parameters in config files.
301+
302+
## Key Design Patterns
303+
304+
1. **Fluent Interface** - All configuration methods return `static` for method chaining
305+
2. **Extension Pattern** - Extensible via DI extensions with `onCompile` callback
306+
3. **Container Caching** - Lazy loading with intelligent cache invalidation
307+
4. **Parameter Substitution** - Both compile-time (static) and runtime (dynamic) parameters
308+
5. **Singleton DI Container** - Generated PHP class with lazy service initialization
309+
310+
## Important Notes
311+
312+
- Container cache key includes PHP version, so cache is invalidated on PHP upgrades
313+
- Dynamic parameters are NOT cached - they're evaluated per request
314+
- Configuration merging uses `DI\Config\Helpers::merge()` for deep array merging
315+
- Debug mode can be forced via cookie secret (useful for production debugging)
316+
- The library has no direct dependency on tracy/tracy (optional integration)

0 commit comments

Comments
 (0)