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 2023/04/29 16:45:53 UTC

[incubator-opendal] branch add-docs-for-core created (now 206bb095)

This is an automated email from the ASF dual-hosted git repository.

xuanwo pushed a change to branch add-docs-for-core
in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git


      at 206bb095 Merge remote-tracking branch 'origin/main' into add-docs-for-core

This branch includes the following new commits:

     new d52a0aff Format code
     new 0e5803b8 Add docs
     new 206bb095 Merge remote-tracking branch 'origin/main' into add-docs-for-core

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[incubator-opendal] 01/03: Format code

Posted by xu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xuanwo pushed a commit to branch add-docs-for-core
in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git

commit d52a0aff66a1c95f7c0d3511391e54a76f351342
Author: Xuanwo <gi...@xuanwo.io>
AuthorDate: Sat Apr 29 19:12:56 2023 +0800

    Format code
    
    Signed-off-by: Xuanwo <gi...@xuanwo.io>
---
 Cargo.toml                            |  1 +
 bindings/java/Cargo.toml              |  3 +--
 bindings/java/src/lib.rs              | 17 +++++++++------
 bindings/ruby/Cargo.toml              |  2 +-
 core/src/raw/http_util/multipart.rs   | 26 +++++++++++++++--------
 core/src/services/gcs/core.rs         |  1 -
 core/src/services/mod.rs              |  1 -
 core/src/services/onedrive/backend.rs | 40 +++++++++++++++++++++++------------
 core/src/services/onedrive/builder.rs | 10 ++++-----
 core/src/services/supabase/backend.rs |  2 +-
 core/src/services/supabase/error.rs   |  5 ++++-
 core/src/types/operator/operator.rs   |  2 +-
 core/tests/behavior/write.rs          |  5 +++--
 rustfmt.toml                          |  7 +++---
 14 files changed, 75 insertions(+), 47 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 986d3cbe..696a5bbc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -19,6 +19,7 @@
 debug = true
 
 [workspace]
+default-members = ["core"]
 members = [
   "core",
 
diff --git a/bindings/java/Cargo.toml b/bindings/java/Cargo.toml
index 06b1fcc6..92612ca5 100644
--- a/bindings/java/Cargo.toml
+++ b/bindings/java/Cargo.toml
@@ -35,8 +35,7 @@ doc = false
 jni = "0.21.1"
 opendal.workspace = true
 
-tokio = { version = "1", features = ["full"] }
 once_cell = "1.17.1"
+tokio = { version = "1", features = ["full"] }
 
 num_cpus = "1.15.0"
-
diff --git a/bindings/java/src/lib.rs b/bindings/java/src/lib.rs
index fc8167ba..1d41d7c8 100644
--- a/bindings/java/src/lib.rs
+++ b/bindings/java/src/lib.rs
@@ -21,19 +21,24 @@ use std::ffi::c_void;
 use std::str::FromStr;
 use std::sync::Arc;
 
+use jni::objects::JClass;
 use jni::objects::JMap;
 use jni::objects::JObject;
 use jni::objects::JString;
-use jni::objects::{JClass, JThrowable, JValue};
-use jni::sys::{jboolean, jint};
-use jni::sys::{jlong, JNI_VERSION_1_8};
-use jni::{JNIEnv, JavaVM};
+use jni::objects::JThrowable;
+use jni::objects::JValue;
+use jni::sys::jboolean;
+use jni::sys::jint;
+use jni::sys::jlong;
+use jni::sys::JNI_VERSION_1_8;
+use jni::JNIEnv;
+use jni::JavaVM;
 use once_cell::sync::OnceCell;
-use tokio::runtime::{Builder, Runtime};
-
 use opendal::BlockingOperator;
 use opendal::Operator;
 use opendal::Scheme;
+use tokio::runtime::Builder;
+use tokio::runtime::Runtime;
 
 static mut RUNTIME: OnceCell<Runtime> = OnceCell::new();
 
diff --git a/bindings/ruby/Cargo.toml b/bindings/ruby/Cargo.toml
index c070193d..57500ea2 100644
--- a/bindings/ruby/Cargo.toml
+++ b/bindings/ruby/Cargo.toml
@@ -34,8 +34,8 @@ name = "opendal_ruby"
 
 [dependencies]
 magnus = { version = "0.5", features = ["bytes-crate"] }
-rb-sys = { version = "0.9.72", default-features = false }
 opendal.workspace = true
+rb-sys = { version = "0.9.72", default-features = false }
 
 [build-dependencies]
 rb-sys-env = "0.1.2"
diff --git a/core/src/raw/http_util/multipart.rs b/core/src/raw/http_util/multipart.rs
index 1bff5df2..6be885bb 100644
--- a/core/src/raw/http_util/multipart.rs
+++ b/core/src/raw/http_util/multipart.rs
@@ -17,14 +17,22 @@
 
 use std::str::FromStr;
 
+use bytes::Bytes;
+use bytes::BytesMut;
+use http::header::CONTENT_DISPOSITION;
+use http::header::CONTENT_LENGTH;
+use http::header::CONTENT_TYPE;
+use http::HeaderMap;
+use http::HeaderName;
+use http::HeaderValue;
+use http::Method;
+use http::Request;
+use http::Uri;
+use http::Version;
+
+use super::new_request_build_error;
+use super::AsyncBody;
 use crate::*;
-use bytes::{Bytes, BytesMut};
-use http::{
-    header::{CONTENT_DISPOSITION, CONTENT_LENGTH, CONTENT_TYPE},
-    HeaderMap, HeaderName, HeaderValue, Method, Request, Uri, Version,
-};
-
-use super::{new_request_build_error, AsyncBody};
 
 /// Multipart is a builder for multipart/form-data.
 #[derive(Debug)]
@@ -312,11 +320,11 @@ impl Part for MixedPart {
 
 #[cfg(test)]
 mod tests {
-    use super::*;
-
     use http::header::CONTENT_TYPE;
     use pretty_assertions::assert_eq;
 
+    use super::*;
+
     #[test]
     fn test_multipart_formdata_basic() {
         let multipart = Multipart::new()
diff --git a/core/src/services/gcs/core.rs b/core/src/services/gcs/core.rs
index 965d58ba..b4b4278c 100644
--- a/core/src/services/gcs/core.rs
+++ b/core/src/services/gcs/core.rs
@@ -24,7 +24,6 @@ use backon::ExponentialBuilder;
 use backon::Retryable;
 use bytes::Bytes;
 use bytes::BytesMut;
-
 use http::header::CONTENT_LENGTH;
 use http::header::CONTENT_RANGE;
 use http::header::CONTENT_TYPE;
diff --git a/core/src/services/mod.rs b/core/src/services/mod.rs
index a74de606..02621986 100644
--- a/core/src/services/mod.rs
+++ b/core/src/services/mod.rs
@@ -141,6 +141,5 @@ mod webhdfs;
 mod onedrive;
 #[cfg(feature = "services-onedrive")]
 pub use onedrive::Onedrive;
-
 #[cfg(feature = "services-webhdfs")]
 pub use webhdfs::Webhdfs;
diff --git a/core/src/services/onedrive/backend.rs b/core/src/services/onedrive/backend.rs
index ce15965e..6e76dccb 100644
--- a/core/src/services/onedrive/backend.rs
+++ b/core/src/services/onedrive/backend.rs
@@ -15,22 +15,34 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use async_trait::async_trait;
-use http::{header, Request, Response, StatusCode};
 use std::fmt::Debug;
 
-use crate::{
-    ops::{OpRead, OpWrite},
-    raw::{
-        build_rooted_abs_path, new_request_build_error, parse_into_metadata, parse_location,
-        percent_encode_path, Accessor, AccessorInfo, AsyncBody, HttpClient, IncomingAsyncBody,
-        RpRead, RpWrite,
-    },
-    types::Result,
-    Capability, Error, ErrorKind,
-};
-
-use super::{error::parse_error, writer::OneDriveWriter};
+use async_trait::async_trait;
+use http::header;
+use http::Request;
+use http::Response;
+use http::StatusCode;
+
+use super::error::parse_error;
+use super::writer::OneDriveWriter;
+use crate::ops::OpRead;
+use crate::ops::OpWrite;
+use crate::raw::build_rooted_abs_path;
+use crate::raw::new_request_build_error;
+use crate::raw::parse_into_metadata;
+use crate::raw::parse_location;
+use crate::raw::percent_encode_path;
+use crate::raw::Accessor;
+use crate::raw::AccessorInfo;
+use crate::raw::AsyncBody;
+use crate::raw::HttpClient;
+use crate::raw::IncomingAsyncBody;
+use crate::raw::RpRead;
+use crate::raw::RpWrite;
+use crate::types::Result;
+use crate::Capability;
+use crate::Error;
+use crate::ErrorKind;
 
 #[derive(Clone)]
 pub struct OnedriveBackend {
diff --git a/core/src/services/onedrive/builder.rs b/core/src/services/onedrive/builder.rs
index b1d020aa..4dc3da91 100644
--- a/core/src/services/onedrive/builder.rs
+++ b/core/src/services/onedrive/builder.rs
@@ -16,12 +16,14 @@
 // under the License.
 
 use std::collections::HashMap;
-use std::fmt::{Debug, Formatter};
+use std::fmt::Debug;
+use std::fmt::Formatter;
 
 use log::debug;
 
 use super::backend::OnedriveBackend;
-use crate::raw::{normalize_root, HttpClient};
+use crate::raw::normalize_root;
+use crate::raw::HttpClient;
 use crate::Scheme;
 use crate::*;
 
@@ -66,9 +68,7 @@ use crate::*;
 ///     // create backend builder
 ///     let mut builder = Onedrive::default();
 ///
-///     builder
-///         .access_token("xxx")
-///         .root("/path/to/root");
+///     builder.access_token("xxx").root("/path/to/root");
 ///
 ///     let op: Operator = Operator::new(builder)?.finish();
 ///     Ok(())
diff --git a/core/src/services/supabase/backend.rs b/core/src/services/supabase/backend.rs
index ae252d08..2b92d2cf 100644
--- a/core/src/services/supabase/backend.rs
+++ b/core/src/services/supabase/backend.rs
@@ -71,7 +71,7 @@ use crate::*;
 ///     builder.key("some_anon_key");
 ///
 ///     let op: Operator = Operator::new(builder)?.finish();
-///    
+///
 ///     Ok(())
 /// }
 /// ```
diff --git a/core/src/services/supabase/error.rs b/core/src/services/supabase/error.rs
index 15017871..54f6c61d 100644
--- a/core/src/services/supabase/error.rs
+++ b/core/src/services/supabase/error.rs
@@ -20,7 +20,10 @@ use http::StatusCode;
 use serde::Deserialize;
 use serde_json::from_slice;
 
-use crate::{raw::*, Error, ErrorKind, Result};
+use crate::raw::*;
+use crate::Error;
+use crate::ErrorKind;
+use crate::Result;
 
 #[derive(Default, Debug, Deserialize)]
 #[serde(default, rename_all = "camelCase")]
diff --git a/core/src/types/operator/operator.rs b/core/src/types/operator/operator.rs
index 8fdd9bf7..ab0a15f7 100644
--- a/core/src/types/operator/operator.rs
+++ b/core/src/types/operator/operator.rs
@@ -1103,10 +1103,10 @@ impl Operator {
     /// # use anyhow::Result;
     /// # use futures::io;
     /// use futures::TryStreamExt;
+    /// use opendal::ops::OpList;
     /// use opendal::EntryMode;
     /// use opendal::Metakey;
     /// use opendal::Operator;
-    /// use opendal::ops::OpList;
     /// # #[tokio::main]
     /// # async fn test(op: Operator) -> Result<()> {
     /// let option = OpList::new().with_limit(10).with_start_after("start");
diff --git a/core/tests/behavior/write.rs b/core/tests/behavior/write.rs
index f98d8642..38f9a3f9 100644
--- a/core/tests/behavior/write.rs
+++ b/core/tests/behavior/write.rs
@@ -15,6 +15,9 @@
 // specific language governing permissions and limitations
 // under the License.
 
+use std::str::FromStr;
+use std::time::Duration;
+
 use anyhow::Result;
 use futures::AsyncReadExt;
 use futures::AsyncSeekExt;
@@ -31,8 +34,6 @@ use opendal::Operator;
 use reqwest::Url;
 use sha2::Digest;
 use sha2::Sha256;
-use std::str::FromStr;
-use std::time::Duration;
 
 use super::utils::*;
 
diff --git a/rustfmt.toml b/rustfmt.toml
index ec3c4bc3..f4c3b57d 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -17,9 +17,10 @@
 
 edition = "2021"
 reorder_imports = true
+
 # format_code_in_doc_comments = true
-# imports_granularity = "Item"
 # group_imports = "StdExternalCrate"
-# where_single_line = true
-# trailing_comma = "Vertical"
+# imports_granularity = "Item"
 # overflow_delimited_expr = true
+# trailing_comma = "Vertical"
+# where_single_line = true


[incubator-opendal] 03/03: Merge remote-tracking branch 'origin/main' into add-docs-for-core

Posted by xu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xuanwo pushed a commit to branch add-docs-for-core
in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git

commit 206bb095e5106eb0e6f5dd3b93b8cc90d22deee6
Merge: 0e5803b8 99ecca73
Author: Xuanwo <gi...@xuanwo.io>
AuthorDate: Sun Apr 30 00:45:45 2023 +0800

    Merge remote-tracking branch 'origin/main' into add-docs-for-core

 Cargo.toml                 |  1 +
 core/src/layers/logging.rs | 28 ++++++++++++++++++++++------
 2 files changed, 23 insertions(+), 6 deletions(-)



[incubator-opendal] 02/03: Add docs

Posted by xu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xuanwo pushed a commit to branch add-docs-for-core
in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git

commit 0e5803b8ee0e4b2533a95dff6c215460ff8bdb1d
Author: Xuanwo <gi...@xuanwo.io>
AuthorDate: Sun Apr 30 00:45:39 2023 +0800

    Add docs
    
    Signed-off-by: Xuanwo <gi...@xuanwo.io>
---
 CONTRIBUTING.md |  68 +++++++++++++++++++++++++--------
 DEVELOPING.md   |  21 +++++++++++
 README.md       | 114 +++++++++++++-------------------------------------------
 3 files changed, 98 insertions(+), 105 deletions(-)

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 4d958aa2..7486df58 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,34 +1,70 @@
 # Contributing
 
-Hello, welcome to the OpenDAL Community! Thanks for your interest in the Apache OpenDAL project! This document will guide you on how to participate in our community and enjoy your time here. 
+First, thank you for contributing to OpenDAL! The goal of this document is to provide everything you need to start contributing to OpenDAL. The following TOC is sorted progressively, starting with the basics and expanding into more specifics.
 
-## Code of Conduct
+- [Your First Contribution](#your-first-contribution)
+- [Workflow](#workflow)
+  - [Git Branches](#git-branches)
+  - [GitHub Pull Requests](#github-pull-requests)
+    - [Title](#title)
+    - [Reviews & Approvals](#reviews--approvals)
+    - [Merge Style](#merge-style)
+    - [CI](#ci)
+- [Next steps](#next-steps)
+- [Code of Conduct](#code-of-conduct)
 
-We expect all community members to follow our [Code of Conduct](https://www.apache.org/foundation/policies/conduct.html).
+## Your First Contribution
+
+1. Ensure your change has an issue! Find an [existing issue](https://github.com/apache/incubator-opendal/issues) or [open a new issue](https://github.com/apache/incubator-opendal/issues/new).
+1. [Fork the OpenDAL repository](https://github.com/apache/incubator-opendal/fork) in your own GitHub account.
+1. [Create a new Git branch](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-and-deleting-branches-within-your-repository).
+1. Make your changes.
+1. [Submit the branch as a pull request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork) to the main OpenDAL repo. An OpenDAL team member should comment and/or review your pull request within a few days. Although, depending on the circumstances, it may take longer.
+
+## Workflow
+
+### Git Branches
+
+*All* changes must be made in a branch and submitted as [pull requests](#github-pull-requests). OpenDAL does not adopt any type of branch naming style, but please use something descriptive of your changes.
 
-## Communication
+### GitHub Pull Requests
 
-We use [GitHub Discussions](https://github.com/apache/incubator-opendal/discussions) for general discussions and questions. Please use the `Q&A` category for questions and the `General` category for general discussions.
+Once your changes are ready you must submit your branch as a [pull request](https://github.com/apache/incubator-opendal/pulls).
 
-We also use [GitHub Issues](https://github.com/apache/incubator-opendal/issues) for bug reports and feature requests.
+#### Title
 
-Otherwise, you can join our [Discord Channel](https://discord.gg/XQy8yGR2dg) for real-time discussions.
+The pull request title must follow the format outlined in the [conventional commits spec](https://www.conventionalcommits.org). [Conventional commits](https://www.conventionalcommits.org) is a standardized format for commit messages. OpenDAL only requires this format for commits on the `main` branch. And because OpenDAL squashes commits before merging branches, this means that only the pull request title must conform to this format.
 
-## Taking Issues
+The following are all good examples of pull request titles:
 
-It is highly recommended to request an assignment before beginning work on any issues to avoid conflicts with other community members.
+```text
+feat(services/gcs): Add start-after support for list
+docs: add hdfs classpath related troubleshoot
+ci: Mark job as skipped if owner is not apache
+fix(services/s3): Ignore prefix if it's empty
+refactor: Polish the implementation of webhdfs
+```
 
-It is encouraged to post your work progress in the issues comment so that the community can stay informed about ongoing developments and offer any necessary assistance.
+#### Reviews & Approvals
 
-It is possible that your assignment has been removed after 14 days of no updates. Please note that this is not a punishment or dissatisfaction from the community. We understand that life can be challenging, and things may not always go as planned.
+All pull requests should be reviewed by at least one OpenDAL committers.
 
-By removing the assignment, we create space for other community members to take over. Additionally, we do not frequently check the assignment due date, so please communicate any stale issues through the issue tracker.
+#### Merge Style
 
-## Sending PRs
+All pull requests are squashed and merged. We generally discourage large pull requests that are over 300-500 lines of diff. If you would like to propose a change that is larger we suggest coming onto our [Discussions](https://github.com/apache/incubator-opendal/discussions) and discuss it with us. This way we can talk through the solution and discuss if a change that large is even needed! This will produce a quicker response to the change and likely produce code that aligns better with o [...]
 
-If you find an issue you would like to fix, open a pull request. For code changes, please refer to the particular component's development guide.
+### CI
 
-We will try our best to review your PRs within 24 hours, and often within 8 hours.
+Currently, Vector uses GitHub Actions to run tests. The workflows are defined in `.github/workflows`.
+
+## Next steps
+
+Visiting **[DEVELOPING.md](DEVELOPING.md)** to prepare Everything necessary to develop.
+
+## Code of Conduct
+
+We expect all community members to follow our [Code of Conduct](https://www.apache.org/foundation/policies/conduct.html).
 
-If a PR does not receive a response within 24 hours, it will be converted to draft status. To indicate that you are ready for review, please mark the PR as `ready for review`.
+---
 
+*This document is highly inspired by [Vector](https://github.com/vectordotdev/vector/)*
diff --git a/DEVELOPING.md b/DEVELOPING.md
new file mode 100644
index 00000000..b7282420
--- /dev/null
+++ b/DEVELOPING.md
@@ -0,0 +1,21 @@
+# Developing
+
+- [Setup](#setup)
+  - [Using a devcontainer environment](#using-a-devcontainer-environment)
+  - [Bring your own toolbox](#bring-your-own-toolbox)
+
+## Setup
+
+We're super excited to have you interested in working on OpenDAL! Before you start you should pick how you want to develop.
+
+For small or first-time contributions, we recommend the devcontainer method. Prefer to do it yourself? That's fine too!
+
+### Using a devcontainer environment
+
+OpenDAL provides a pre-configued [devcontainer](https://containers.dev/) that could be used in [Github Codespaces](https://github.com/features/codespaces), [VSCode](https://code.visualstudio.com/), [JetBrains](https://www.jetbrains.com/remote-development/gateway/), [JuptyerLab](https://jupyterlab.readthedocs.io/en/stable/). Please pick up your favourite runtime environment.
+
+The fastest way is [click here to create a new codespace for OpenDAL](https://github.com/codespaces/new?skip_quickstart=true&machine=standardLinux32gb&repo=459025965&ref=main).
+
+---
+
+*This document is highly inspired by [Vector](https://github.com/vectordotdev/vector/)*
diff --git a/README.md b/README.md
index 74a48fc4..1c59f4c9 100644
--- a/README.md
+++ b/README.md
@@ -1,102 +1,44 @@
+<p align="center">
 <picture>
   <source media="(prefers-color-scheme: dark)" srcset="website/static/img/logo_dark.svg">
   <img alt="Apache OpenDAL(incubating)" src="website/static/img/logo.svg" width="300px">
 </picture>
 
-[![Build Status]][actions] [![chat]][discord]
+**Open** **D**ata **A**ccess **L**ayer
+</p>
 
-[build status]: https://img.shields.io/github/actions/workflow/status/apache/incubator-opendal/ci.yml?branch=main
-[actions]: https://github.com/apache/incubator-opendal/actions?query=branch%3Amain
-[chat]: https://img.shields.io/discord/1081052318650339399
-[discord]: https://discord.gg/XQy8yGR2dg
+---
 
-**Open** **D**ata **A**ccess **L**ayer: Access data freely, painlessly, and efficiently
+## Access Data Freely
 
-![](https://user-images.githubusercontent.com/5351546/222356748-14276998-501b-4d2a-9b09-b8cff3018204.png)
-
-## Components
-
-- [core](core/README.md): OpenDAL Rust Core
-  - Documentation: [stable](https://docs.rs/opendal/) | [main](https://opendal.apache.org/docs/rust/opendal/)
-- [binding-c](bindings/c): OpenDAL C Binding (working on)
-- [binding-java](bindings/java): OpenDAL Java Binding (working on)
-- [binding-nodejs](bindings/nodejs/README.md): OpenDAL Node.js Binding
-  - Documentation: [main](https://opendal.apache.org/docs/nodejs/)
-- [binding-python](bindings/python/README.md): OpenDAL Python Binding
-  - Documentation: [main](https://opendal.apache.org/docs/python/)
-- [binding-ruby](bindings/ruby): OpenDAL Ruby Binding (working on)
-- bin
-  - [oli](bin/oli): OpenDAL Command Line Interface
-
-## Quickstart
-
-### Rust
-
-```rust
-use opendal::Result;
-use opendal::layers::LoggingLayer;
-use opendal::services;
-use opendal::Operator;
-
-#[tokio::main]
-async fn main() -> Result<()> {
-    // Pick a builder and configure it.
-    let mut builder = services::S3::default();
-    builder.bucket("test");
-
-    // Init an operator
-    let op = Operator::new(builder)?
-        // Init with logging layer enabled.
-        .layer(LoggingLayer::default())
-        .finish();
+OpenDAL is a data access layer that allows users to easily and efficiently retrieve data from various storage services in an unified way.
 
-    // Write data
-    op.write("hello.txt", "Hello, World!").await?;
-
-    // Read data
-    let bs = op.read("hello.txt").await?;
-
-    // Fetch metadata
-    let meta = op.stat("hello.txt").await?;
-    let mode = meta.mode();
-    let length = meta.content_length();
-
-    // Delete
-    op.delete("hello.txt").await?;
-
-    Ok(())
-}
-```
+![](https://user-images.githubusercontent.com/5351546/222356748-14276998-501b-4d2a-9b09-b8cff3018204.png)
 
-### Python
+Major components of the project include:
 
-```python
-import asyncio
+**Libraries**
 
-async def main():
-    op = opendal.AsyncOperator("fs", root="/tmp")
-    await op.write("test.txt", b"Hello World")
-    print(await op.read("test.txt"))
+- [Rust Core](core/README.md)
+- [Node.js Binding](bindings/nodejs/README.md)
+- [Python Binding](bindings/python/README.md)
+- [C Binding](bindings/c) *working on*
+- [Java Binding](bindings/java) *working on*
+- [Ruby Binding](bindings/ruby): *working on*
 
-asyncio.run(main())
-```
+**Applications**
 
-### Node.js
+- [oli](bin/oli): OpenDAL Command Line Interface
+- [oay](bin/oay): OpenDAL Gateway
 
-```js
-import { Operator } from "opendal";
+## How to contribute OpenDAL
 
-async function main() {
-  const op = new Operator("fs", { root: "/tmp" });
-  await op.write("test", "Hello, World!");
-  const bs = await op.read("test");
-  console.log(new TextDecoder().decode(bs));
-  const meta = await op.stat("test");
-  console.log(`contentLength: ${meta.contentLength}`);
-}
-```
+- Start with [Contributing Guide](CONTRIBUTING.md)
+- Submit [Issues](https://github.com/apache/incubator-opendal/issues/new) for bug report or feature requests.
+- Asking questions in the [Discussions](https://github.com/apache/incubator-opendal/discussions/new?category=q-a).
+- Talk to community at [Discord](https://discord.gg/XQy8yGR2dg).
 
-## Projects
+## Who uses OpenDAL
 
 - [Databend](https://github.com/datafuselabs/databend/): A modern Elasticity and Performance cloud data warehouse.
 - [GreptimeDB](https://github.com/GreptimeTeam/greptimedb): An open-source, cloud-native, distributed time-series database.
@@ -105,12 +47,6 @@ async function main() {
 - [risingwave](https://github.com/risingwavelabs/risingwave): A Distributed SQL Database for Stream Processing
 - [Vector](https://github.com/vectordotdev/vector): A high-performance observability data pipeline.
 
-## Getting help
-
-Submit [issues](https://github.com/apache/incubator-opendal/issues/new) for bug report or asking questions in the [Discussions forum](https://github.com/apache/incubator-opendal/discussions/new?category=q-a).
-
-Talk to develops at [discord].
-
 ## License
 
-Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
+Licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)