kopi 0.2.1

Kopi is a JDK version management tool
Documentation
# Kopi Development Guide

This guide contains technical information for developers working on the Kopi codebase.

## Debugging and Logging

Kopi provides flexible logging controls for troubleshooting and debugging:

### Verbosity Levels

Use the `-v/--verbose` flag (can be specified multiple times) with any command:

```bash
kopi install 21              # Default: warnings and errors only
kopi -v install 21           # Info level: show major operations
kopi -vv install 21          # Debug level: detailed flow information
kopi -vvv install 21         # Trace level: very detailed debugging
```

The verbose flag is global and works with all commands:

```bash
kopi -v list                 # Show info logs for list command
kopi -vv shell 21            # Debug version switching (alias: use)
kopi -vvv current            # Trace current version detection
```

### Environment Variable Control

For persistent logging or module-specific debugging, use the `RUST_LOG` environment variable:

```bash
# Set logging level for entire session
export RUST_LOG=debug
kopi install 21

# Debug specific modules
RUST_LOG=kopi::download=debug kopi install 21        # Debug downloads only
RUST_LOG=kopi::api=trace kopi cache search latest    # Trace API calls
RUST_LOG=kopi::storage=debug kopi uninstall temurin@21  # Debug storage operations

# Multiple module filters
RUST_LOG=kopi::download=debug,kopi::security=trace kopi install 21
```

### Common Debugging Scenarios

**Installation Issues:**

```bash
kopi -vv install 21          # See download URLs, checksums, extraction paths
```

**Version Resolution Problems:**

```bash
RUST_LOG=kopi::version=debug kopi install temurin@21  # Debug version parsing
```

**API Communication:**

```bash
RUST_LOG=kopi::api=debug kopi cache search latest     # Debug foojay.io API calls
```

**Storage and Disk Space:**

```bash
RUST_LOG=kopi::storage=debug kopi -v install 21       # Debug installation paths
```

## Security Considerations

Kopi implements several security measures to ensure safe operation:

### Path Validation

- Persistent artefacts (JDKs, shims, cache files) are created via `paths::*` helpers under `KOPI_HOME` (`~/.kopi` by default); temporary downloads use OS temp space but are moved back into Kopi-managed directories before use
- Path traversal attempts (e.g., `../../../etc/passwd`) are blocked by `shim::security::SecurityValidator::validate_path`
- Symlinks are validated (`validate_symlink`) to ensure they remain inside Kopi home

### Version String Validation

- Version strings are validated to contain only safe characters (alphanumeric, `@`, `.`, `-`, `_`, `+`)
- Maximum length of 100 characters enforced
- Special patterns that could be used for injection attacks are rejected

### Tool Validation

- Only recognized JDK tools can be shimmed
- Unknown or system commands (e.g., `rm`, `curl`) are rejected
- Tool names are validated against a comprehensive registry

### File Permission Checks

- Shim targets must be executable files
- On Unix systems, world-writable files are rejected
- Regular file validation ensures directories cannot be executed

### Auto-Install Security

- When `auto_install.prompt` is enabled (default), Kopi asks for confirmation before fetching missing JDKs; disabling the prompt allows unattended installs
- Installation subprocesses are terminated if they exceed the configurable `auto_install.timeout_secs` budget
- Version strings are validated before installation attempts

### Best Practices

1. **Regular Updates**: Keep kopi updated to get the latest security fixes
2. **Verify Downloads**: Kopi automatically verifies checksums for all JDK downloads
3. **Permission Management**: Ensure `~/.kopi` directory has appropriate permissions
4. **Audit Shims**: Periodically run `kopi shim verify` to check shim integrity

## Performance Characteristics

### Shim Overhead

Kopi's shims are designed for minimal performance impact. The automated regression in `tests/shim_performance_test.rs` keeps average invocation latency below 50 ms and validates that metadata caching further improves warm-path execution on Unix-like platforms.

- **Cold start (average)**: < 50 ms in the cross-platform performance suite
- **Warm start**: Faster once `<distribution>-<version>.meta.json` descriptors exist alongside the JDK
- **Total overhead**: Remains well below JVM startup times, keeping overall session cost dominated by the Java process

### Performance Optimizations

1. **Release Profile**: Shims are built with a custom `release-shim` profile
   - Link-time optimization (LTO) enabled
   - Single codegen unit for better optimization
   - Debug symbols stripped

2. **Centralised Tool Registry**: `shim::tools::ToolRegistry` defines the supported command surface, keeping validation and discovery consistent across distributions

3. **Fast Version Resolution**:
   - Checks `KOPI_JAVA_VERSION` before touching the filesystem
   - Walks parent directories for `.kopi-version` / `.java-version` and stops at the first match
   - Falls back to the global default stored in `~/.kopi/version`

4. **Platform-Specific Optimizations**:
   - Direct process replacement on Unix (exec)
   - Efficient subprocess spawning on Windows

### Comparison with Direct Execution

The shim overhead is negligible compared to JVM startup time:

- JVM cold start: typically hundreds of milliseconds
- Shim overhead: < 50 ms average in continuous tests (a small fraction of total startup time)

## Debugging Environment Variables

- `RUST_LOG` - Control logging verbosity (see Debugging and Logging section)

## Exit Codes

Kopi uses specific exit codes to help with scripting and automation:

- `0`: Success
- `1`: General error (fallback for uncategorised failures)
- `2`: Invalid input or configuration error
- `3`: No local version found
- `4`: JDK not installed
- `5`: Requested tool not found in the active JDK
- `6`: Shell detection failed
- `7`: Unsupported shell
- `13`: Permission denied
- `17`: Resource already exists
- `20`: Network, HTTP, or metadata fetch error
- `28`: Disk space error
- `75`: Lock acquisition cancelled by user signal
- `127`: Command or shell not found