This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
While working on OpenDAL, please remember:
core directory.core must pass the clippy check and behavior tests.# Check code cargo check # Build cargo build # Run linter for all services. cargo clippy --all-targets --all-features -- -D warnings # Run linter for specific services. cargo clippy --all-targets --features=services-s3 -- -D warnings # Run tests (requires test features) cargo test --features tests # Run behavior tests OPENDAL_TEST=s3 cargo test --features services-s3,tests behavior # Run specific test cargo test tests::it::services::fs # Format code cargo fmt # Check formatting cargo fmt --check # Build documentation cargo doc --lib --no-deps --all-features # Run benchmarks cargo bench
# Run command across all packages ./scripts/workspace.py cargo check ./scripts/workspace.py cargo fmt -- --check
# Generate bindings code just generate python just generate java # Update version across project just update-version # Release process just release
# Copy environment template for tests cp .env.example .env # Edit .env with your service credentials
OpenDAL is a unified data access layer with a modular architecture:
src/services/: 50+ storage service implementations (S3, Azure, GCS, etc.)src/layers/: Middleware for cross-cutting concerns (retry, metrics, tracing)src/raw/: Low-level traits and types for implementing backendssrc/types/: Core types and traitsEach service follows a consistent structure:
backend.rs: Main service implementation with Accessor traitconfig.rs: Configuration and builder patterncore.rs: Core logic and HTTP client setupwriter.rs, reader.rs, lister.rs: Operation implementationserror.rs: Service-specific error handlingdev crate for consistencyServices are feature-gated to reduce binary size:
// Enable specific services [features] services-s3 = [] services-azblob = []
Layers provide composable middleware:
op.layer(RetryLayer::new()) .layer(MetricsLayer::new()) .layer(LoggingLayer::new())
All core operations are async with blocking wrappers available:
// Async API let data = op.read("path").await?; // Blocking API let data = op.blocking().read("path")?;
Use conventional commits:
feat(services/gcs): Add start-after support for list fix(services/s3): Ignore prefix if it's empty docs: Add troubleshooting guide ci: Update GitHub Actions workflow refactor(core): Simplify error handling
src/tests/.envcore/src/services/Accessor traitCargo.tomlRUST_LOG=debugAccessor traitjust for common development tasks