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/03/26 11:02:45 UTC

[incubator-opendal] branch main updated: feat(oli): implement `oli rm` (#1774)

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/incubator-opendal.git


The following commit(s) were added to refs/heads/main by this push:
     new 51410fbf feat(oli): implement `oli rm` (#1774)
51410fbf is described below

commit 51410fbfe43aea429c99b374b1be15fbb94cb7c0
Author: Jian Zeng <an...@gmail.com>
AuthorDate: Sun Mar 26 19:02:41 2023 +0800

    feat(oli): implement `oli rm` (#1774)
    
    Signed-off-by: Jian Zeng <an...@gmail.com>
---
 bin/oli/src/bin/oli.rs      |  4 +++
 bin/oli/src/commands/cli.rs |  2 ++
 bin/oli/src/commands/mod.rs |  1 +
 bin/oli/src/commands/rm.rs  | 78 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 85 insertions(+)

diff --git a/bin/oli/src/bin/oli.rs b/bin/oli/src/bin/oli.rs
index 2e5a2f9d..32861b4e 100644
--- a/bin/oli/src/bin/oli.rs
+++ b/bin/oli/src/bin/oli.rs
@@ -77,6 +77,10 @@ async fn main() -> Result<()> {
             let cmd = oli::commands::ls::cli(new_cmd("ols")?);
             oli::commands::ls::main(&cmd.get_matches()).await?;
         }
+        Some("orm") => {
+            let cmd = oli::commands::rm::cli(new_cmd("orm")?);
+            oli::commands::rm::main(&cmd.get_matches()).await?;
+        }
         Some(v) => {
             println!("{v} is not supported")
         }
diff --git a/bin/oli/src/commands/cli.rs b/bin/oli/src/commands/cli.rs
index d176583a..7a531309 100644
--- a/bin/oli/src/commands/cli.rs
+++ b/bin/oli/src/commands/cli.rs
@@ -25,6 +25,7 @@ pub async fn main(args: &ArgMatches) -> Result<()> {
         Some(("cat", sub_args)) => super::cat::main(sub_args).await?,
         Some(("cp", sub_args)) => super::cp::main(sub_args).await?,
         Some(("ls", sub_args)) => super::ls::main(sub_args).await?,
+        Some(("rm", sub_args)) => super::rm::main(sub_args).await?,
         _ => return Err(anyhow!("not handled")),
     }
 
@@ -37,4 +38,5 @@ pub fn cli(cmd: Command) -> Command {
         .subcommand(super::cat::cli(Command::new("cat")))
         .subcommand(super::cp::cli(Command::new("cp")))
         .subcommand(super::ls::cli(Command::new("ls")))
+        .subcommand(super::rm::cli(Command::new("rm")))
 }
diff --git a/bin/oli/src/commands/mod.rs b/bin/oli/src/commands/mod.rs
index 0347b404..2e97d48d 100644
--- a/bin/oli/src/commands/mod.rs
+++ b/bin/oli/src/commands/mod.rs
@@ -37,3 +37,4 @@ pub mod cat;
 pub mod cli;
 pub mod cp;
 pub mod ls;
+pub mod rm;
diff --git a/bin/oli/src/commands/rm.rs b/bin/oli/src/commands/rm.rs
new file mode 100644
index 00000000..df72a0fc
--- /dev/null
+++ b/bin/oli/src/commands/rm.rs
@@ -0,0 +1,78 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use std::collections::VecDeque;
+use std::path::PathBuf;
+
+use anyhow::{anyhow, Result};
+use clap::{Arg, ArgAction, ArgMatches, Command};
+use futures::TryStreamExt;
+use opendal::Metakey;
+
+use crate::config::Config;
+
+pub async fn main(args: &ArgMatches) -> Result<()> {
+    let config_path = args
+        .get_one::<PathBuf>("config")
+        .ok_or_else(|| anyhow!("missing config path"))?;
+    let cfg = Config::load(config_path)?;
+
+    let recursive = args.get_flag("recursive");
+
+    let target = args
+        .get_one::<String>("target")
+        .ok_or_else(|| anyhow!("missing target"))?;
+    let (op, path) = cfg.parse_location(target)?;
+
+    if !recursive {
+        println!("Delete: {path}");
+        op.delete(&path).await?;
+        return Ok(());
+    }
+
+    let mut queue = VecDeque::from([path.to_string()]);
+    while !queue.is_empty() {
+        let path = queue.pop_front().unwrap();
+        let mut ds = op.list(&path).await?;
+        while let Some(de) = ds.try_next().await? {
+            let meta = op.metadata(&de, Metakey::Mode).await?;
+            if meta.mode().is_dir() {
+                let d = de.path().to_owned();
+                queue.push_back(d);
+            } else {
+                let path = de.path();
+                println!("Delete: {path}");
+                op.delete(path).await?;
+            }
+        }
+    }
+    Ok(())
+}
+
+pub fn cli(cmd: Command) -> Command {
+    cmd.version("0.10.0")
+        .about("remove object")
+        .arg(Arg::new("target").required(true))
+        .arg(
+            Arg::new("recursive")
+                .required(false)
+                .long("recursive")
+                .short('r')
+                .help("List recursively")
+                .action(ArgAction::SetTrue),
+        )
+}