You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@opendal.apache.org by xu...@apache.org on 2026/06/05 08:12:29 UTC
(opendal) branch main updated: docs: Sync AGENTS.md with current layout (#7677)
This is an automated email from the ASF dual-hosted git repository.
Xuanwo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/opendal.git
The following commit(s) were added to refs/heads/main by this push:
new 845214194 docs: Sync AGENTS.md with current layout (#7677)
845214194 is described below
commit 8452141943572fd05b3f83b5e2e3778cdf5a9935
Author: Xuanwo <gi...@xuanwo.io>
AuthorDate: Fri Jun 5 16:12:21 2026 +0800
docs: Sync AGENTS.md with current layout (#7677)
---
AGENTS.md | 237 +++++++++++++++++++++++++-------------------------------------
1 file changed, 97 insertions(+), 140 deletions(-)
diff --git a/AGENTS.md b/AGENTS.md
index 44a294f60..fe4f0dd0f 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -1,181 +1,138 @@
# AGENTS.md
-This file provides guidance to AI coding agents (e.g., Claude Code, ChatGPT) when working with code in this repository.
+Guidance for AI coding agents working in this repository.
-While working on OpenDAL, please remember:
+## General Rules
-- Always use English in code and comments.
-- Only add meaningful comments when the code's behavior is difficult to understand.
-- Only add meaningful tests when they actually verify internal behaviors; otherwise, don't create them unless requested.
+- Use English in repository files: code, comments, commit messages, PR titles, PR bodies, and technical docs.
+- Add comments only when they explain non-obvious intent or constraints.
+- Add tests when they verify real behavior or guard a regression; do not add placeholder tests.
+- Do not change public APIs or behavior tests unless the task explicitly requires it.
-## Build and Development Commands
+## Rust Workspace Commands
-### Core Rust Development
-
-- All cargo commands must be executed within the `core` directory.
-- All changes to `core` must pass the clippy check and behavior tests.
-- Don't change public API or behavior tests unless requested.
+The Rust workspace for OpenDAL core lives under `core/`. There is no root `Cargo.toml`; run core cargo commands from `core/`.
```bash
-# Check code
-cargo check
+cd core
-# Build
-cargo build
+# Check and build
+cargo check
+cargo build --locked
+cargo build --all-features --locked
-# Run linter for all services.
-cargo clippy --all-targets --all-features -- -D warnings
+# Lint, matching Core CI
+cargo clippy --workspace --all-targets --all-features -- -D warnings
-# Run linter for specific services.
+# Lint a focused service/layer feature set
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
+# Unit tests, matching Core CI
+cargo nextest run --workspace --no-fail-fast --all-features
-# Build documentation
+# Doc tests and docs
+cargo test --workspace --doc --all-features
cargo doc --lib --no-deps --all-features
-# Run benchmarks
-cargo bench
+# Behavior tests
+OPENDAL_TEST=s3 cargo test behavior --features tests,services-s3
+
+# Format core workspace
+cargo fmt --all
+cargo fmt --all -- --check
```
-### Multi-package Operations
+Repository-wide format checks run from the repository root:
+
```bash
-# Run command across all packages
-./scripts/workspace.py cargo check
./scripts/workspace.py cargo fmt -- --check
+taplo format --check
```
-### Code Generation and Release
+Code generation and release helpers also run from the repository root:
+
```bash
-# Generate bindings code
just generate python
just generate java
-
-# Update version across project
just update-version
-
-# Release process
just release
```
-### Testing Setup
-```bash
-# Copy environment template for tests
-cp .env.example .env
-# Edit .env with your service credentials
-```
+## Current Architecture
-## Architecture Overview
-
-OpenDAL is a unified data access layer with a modular architecture:
-
-### Core Structure
-- **core/**: Main Rust library implementing the storage abstraction
- - `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 backends
- - `src/types/`: Core types and traits
-
-### Service Implementation Pattern
-Each service follows a consistent structure:
-- `backend.rs`: Main service implementation with `Accessor` trait
-- `config.rs`: Configuration and builder pattern
-- `core.rs`: Core logic and HTTP client setup
-- `writer.rs`, `reader.rs`, `lister.rs`: Operation implementations
-- `error.rs`: Service-specific error handling
-
-### Language Bindings
-- **bindings/**: Language-specific bindings (Python, Java, Go, Node.js, etc.)
- - Each binding has its own build system and contributing guide
- - Generated code uses the `dev` crate for consistency
-
-### Applications
-- oli: moved to a separate repository (see docs: https://opendal.apache.org/docs/40-apps/oli)
-- ofs: moved to a separate repository (see docs: https://opendal.apache.org/docs/40-apps/ofs)
-- oay: removed from this repository
-
-### Integrations
-- **integrations/**: Ecosystem integrations (FUSE, WebDAV, object_store)
-
-## Key Development Patterns
-
-### Feature Flags
-Services are feature-gated to reduce binary size:
-```rust
-// Enable specific services
-[features]
-services-s3 = []
-services-azblob = []
-```
+OpenDAL's Rust core has been split into a facade crate plus smaller core, service, and layer crates.
-### Layer System
-Layers provide composable middleware:
-```rust
-op.layer(RetryLayer::new())
- .layer(MetricsLayer::new())
- .layer(LoggingLayer::new())
-```
+- `core/Cargo.toml`: Rust workspace root and `opendal` facade package.
+- `core/src/lib.rs`: facade crate that re-exports `opendal-core`, wires optional service/layer crates, and registers enabled services for `Operator::from_uri` / `Operator::via_iter`.
+- `core/core/`: `opendal-core`, containing public core types, raw traits, shared layers, HTTP utilities, docs, RFCs, and the always-available memory service.
+- `core/services/<service>/`: standalone service crates named `opendal-service-*`.
+- `core/layers/<layer>/`: standalone layer crates named `opendal-layer-*`.
+- `core/testkit/`: behavior-test support.
+- `core/tests/behavior/`: core behavior test entrypoint.
+- `integrations/`: ecosystem integrations such as `object_store`, `parquet`, `dav-server`, `unftp-sbe`, and Spring.
+- `bindings/`: language bindings; each binding has its own build/test conventions.
+- `website/`: documentation website.
+- `dev/`: repository maintenance, code generation, and release tooling used by `just`.
-### Async-First Design
-All core operations are async with blocking wrappers available:
-```rust
-// Async API
-let data = op.read("path").await?;
+Important consequences of the split:
-// Blocking API
-let data = op.blocking().read("path")?;
-```
+- Service and layer code no longer lives under `core/src/services` or `core/src/layers`.
+- Public API changes usually touch `core/core/src/...` and the facade exports in `core/src/lib.rs`.
+- Optional user-facing features are declared in `core/Cargo.toml` as `services-*` and `layers-*`, and usually map to optional `opendal-service-*` / `opendal-layer-*` dependencies.
+- The memory service is in `core/core/src/services/memory`; `services-memory` is a deprecated compatibility feature because memory is always enabled.
-## Commit Message Format
-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
-```
+## Service Implementation Pattern
+
+Most services follow this shape under `core/services/<name>/`:
+
+- `src/lib.rs`: crate docs, module declarations, public builder/config exports, and service registration function.
+- `src/backend.rs`: builder and `opendal_core::raw::Access` implementation.
+- `src/config.rs`: serializable config and builder conversion.
+- `src/core.rs`: shared service client, request construction, and service-specific helpers.
+- `src/error.rs`: service-specific error parsing.
+- `src/reader.rs`, `src/writer.rs`, `src/lister.rs`, `src/deleter.rs`, `src/copier.rs`: operation implementations when the service needs them.
+- `src/docs.md`: service docs included into rustdoc.
-## Pull Request Requirements
-- Always follow OpenDAL's pull request template when creating a PR.
+When adding or changing a service:
-## Testing Approach
-- Unit tests in `src/tests/`
-- Behavior tests validate service implementations
-- Integration tests require service credentials in `.env`
-- CI runs tests across multiple platforms and Rust versions
+1. Put implementation in `core/services/<service>/`.
+2. Implement `Builder` and `Access` using `opendal_core`.
+3. Add or update the facade feature and optional dependency in `core/Cargo.toml`.
+4. Register the service in `core/src/lib.rs` when it should support URI/iterator construction.
+5. Add or update behavior-test setup under `.github/services/<service>/` when real backend testing is needed.
+6. Run focused clippy/tests first, then broaden validation based on the blast radius.
-## Common Tasks
+## Layer Implementation Pattern
-### Adding a New Service
-1. Create new module in `core/src/services/`
-2. Implement `Accessor` trait
-3. Add service feature flag in `Cargo.toml`
-4. Add service tests in behavior test suite
-5. Update documentation
+Reusable layers live under `core/layers/<layer>/` as `opendal-layer-*` crates. Core layers that are required by `opendal-core` itself live under `core/core/src/layers/`.
-### Debugging Service Issues
-1. Enable debug logging: `RUST_LOG=debug`
-2. Use tracing layer for detailed operation tracking
-3. Check service-specific error types
-4. Verify credentials and endpoint configuration
+When adding or changing a public optional layer:
+
+1. Put reusable optional code in `core/layers/<layer>/`.
+2. Depend on `opendal-core` and implement `Layer` / `LayeredAccess` against `opendal_core::raw`.
+3. Add or update the corresponding `layers-*` feature and optional dependency in `core/Cargo.toml`.
+4. Re-export it from the facade when users should access it through `opendal::layers`.
+
+## Testing Expectations
+
+- Use `cargo fmt --all -- --check` for Rust formatting inside `core/`; use `./scripts/workspace.py cargo fmt -- --check` for the repository-wide format check.
+- For core changes, `cargo clippy --workspace --all-targets --all-features -- -D warnings` is the CI-level lint gate.
+- For behavior changes, run the narrow behavior test, for example `OPENDAL_TEST=s3 cargo test behavior --features tests,services-s3`.
+- Behavior tests require backend credentials or fixture setup. Use `.env.example`, `fixtures/`, and `.github/services/<service>/` as the source of truth for service-specific setup.
+- Integration crates under `integrations/` have their own CI workflows and should be validated in their own directories when touched.
+- Binding changes should follow the binding's local README/build files and the matching `.github/workflows/ci_bindings_*.yml`.
+
+## Pull Requests
+
+- Always use `.github/pull_request_template.md` when creating a PR.
+- Keep PR titles and descriptions factual and concise.
+- Do not add AI-tool branding or co-author trailers.
+- If public APIs or user-facing behavior change, update docs and call out the user-facing impact in the PR template.
## Important Notes
-- Minimum Rust version: 1.85 (MSRV)
-- All services implement the same `Accessor` trait
-- Use `just` for common development tasks
-- Check CI workflows for platform-specific requirements
-- Services are tested against real backends (credentials required)
+
+- Minimum Rust version is 1.85, configured in `core/Cargo.toml` and checked by CI.
+- Use `opendal_core::raw::Access`, `Layer`, and `LayeredAccess` for internal implementations.
+- Use `opendal_core::raw::oio::{ReadStream, Write, List, Delete}` for operation bodies.
+- Use `Operator` and `blocking::Operator` as the public API entry points.
+- Prefer existing helpers in `opendal-core` before adding service-local utilities.