Skip to content

Commit

Permalink
new rm command #15
Browse files Browse the repository at this point in the history
  • Loading branch information
sagiegurari committed Jan 2, 2020
1 parent b78304c commit a18ae71
Show file tree
Hide file tree
Showing 12 changed files with 304 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

### v0.1.2

* New **rm** command #15
* New **rmdir** command #14
* New **assert_eq** command #22
* New **assert_fail** command #3
Expand Down
35 changes: 34 additions & 1 deletion docs/sdk.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* [sdk::fs::CreateDirectory](#sdk__fs__CreateDirectory)
* [sdk::fs::CreateEmptyFile](#sdk__fs__CreateEmptyFile)
* [sdk::fs::DeleteEmptyDirectory](#sdk__fs__DeleteEmptyDirectory)
* [sdk::fs::DeletePath](#sdk__fs__DeletePath)
* [sdk::fs::GetCanonicalPath](#sdk__fs__GetCanonicalPath)
* [sdk::fs::GetFileName](#sdk__fs__GetFileName)
* [sdk::fs::GetParentDirectory](#sdk__fs__GetParentDirectory)
Expand Down Expand Up @@ -806,7 +807,7 @@ var = rmdir path
```
This command delete the requested empty directory and returns true if successful.<br>
If the path leads to a file or the directory is not empty, this command will fail.
If the path leads to a file or a directory which is not empty, this command will fail.
#### Parameters
Expand All @@ -826,6 +827,38 @@ deleted = rmdir ./mydir
#### Aliases:
rmdir
<a name="sdk__fs__DeletePath"></a>
## sdk::fs::DeletePath
```sh
var = rm [-r] path
```
This command delete the requested file, empty directory or recursively deletes a directory
and all its content (files and sub directories) if the **-r** flag is provided.
#### Parameters
* Optional flags (currently only -r is supported which indicates recursive deletion)
* The path to delete
#### Return Value
**true** if the path was deleted.
#### Examples
```sh
# delete a file or empty directory
deleted = rm ./target
# deletes a directory and all its content
deleted = rm -r ./target
```
#### Aliases:
rm
<a name="sdk__fs__GetCanonicalPath"></a>
## sdk::fs::GetCanonicalPath
```sh
Expand Down
2 changes: 2 additions & 0 deletions duckscript_sdk/src/sdk/std/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod dirname;
mod mkdir;
mod print;
mod read;
mod rm;
mod rmdir;
mod touch;
mod write;
Expand All @@ -23,6 +24,7 @@ pub(crate) fn load(commands: &mut Commands, parent: &str) -> Result<(), ScriptEr
commands.set(mkdir::create(&package))?;
commands.set(print::create(&package))?;
commands.set(read::create(&package))?;
commands.set(rm::create(&package))?;
commands.set(rmdir::create(&package))?;
commands.set(touch::create(&package))?;
commands.set(write::create(&package))?;
Expand Down
25 changes: 25 additions & 0 deletions duckscript_sdk/src/sdk/std/fs/rm/help.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
```sh
var = rm [-r] path
```

This command delete the requested file, empty directory or recursively deletes a directory
and all its content (files and sub directories) if the **-r** flag is provided.

#### Parameters

* Optional flags (currently only -r is supported which indicates recursive deletion)
* The path to delete

#### Return Value

**true** if the path was deleted.

#### Examples

```sh
# delete a file or empty directory
deleted = rm ./target

# deletes a directory and all its content
deleted = rm -r ./target
```
64 changes: 64 additions & 0 deletions duckscript_sdk/src/sdk/std/fs/rm/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use crate::utils::{flags, pckg};
use duckscript::types::command::{Command, CommandResult};
use std::fs;
use std::path::Path;

#[cfg(test)]
#[path = "./mod_test.rs"]
mod mod_test;

struct CommandImpl {
package: String,
}

impl Command for CommandImpl {
fn name(&self) -> String {
pckg::concat(&self.package, "DeletePath")
}

fn aliases(&self) -> Vec<String> {
vec!["rm".to_string()]
}

fn help(&self) -> String {
include_str!("help.md").to_string()
}

fn run(&self, arguments: Vec<String>) -> CommandResult {
if arguments.is_empty() {
CommandResult::Error("Path not provided.".to_string())
} else {
let (path_str, recursive) = if arguments.len() == 1 {
(&arguments[0], false)
} else if flags::is_unix_flags_argument(&arguments[0]) {
let recursive = flags::is_unix_flag_exists('r', &arguments[0]);
(&arguments[1], recursive)
} else {
(&arguments[0], false)
};

let path = Path::new(path_str);

let result = if !path.exists() {
Ok(())
} else if path.is_file() {
fs::remove_file(&arguments[0])
} else if recursive {
fs::remove_dir_all(&path)
} else {
fs::remove_dir(&path)
};

match result {
Ok(_) => CommandResult::Continue(Some("true".to_string())),
Err(error) => CommandResult::Error(error.to_string()),
}
}
}
}

pub(crate) fn create(package: &str) -> Box<dyn Command> {
Box::new(CommandImpl {
package: package.to_string(),
})
}
63 changes: 63 additions & 0 deletions duckscript_sdk/src/sdk/std/fs/rm/mod_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use super::*;
use crate::test;
use crate::test::CommandValidation;
use crate::utils::io;

#[test]
fn common_functions() {
test::test_common_command_functions(create(""));
}

#[test]
fn run_no_path_provided() {
test::run_script_and_fail(vec![create("")], "rm");
}

#[test]
fn run_path_not_exists() {
test::run_script_and_validate(
vec![create("")],
"out = rm ./target/_duckscript/rm/newdir",
CommandValidation::Match("out".to_string(), "true".to_string()),
);
}

#[test]
fn run_path_not_empty_not_recursive() {
let result = io::create_directory("./target/_duckscript/rm/not_empty/dir1");
assert!(result.is_ok());

test::run_script_and_fail(vec![create("")], "rm ./target/_duckscript/rm/not_empty");
}

#[test]
fn run_path_is_file() {
let path = Path::new("./target/_duckscript/rm/file.txt");
let result = io::create_empty_file("./target/_duckscript/rm/file.txt");
assert!(result.is_ok());
assert!(path.exists());

test::run_script_and_validate(
vec![create("")],
"out = rm ./target/_duckscript/rm/file.txt",
CommandValidation::Match("out".to_string(), "true".to_string()),
);

assert!(!path.exists());
}

#[test]
fn run_path_recursive() {
let path = Path::new("./target/_duckscript/rm/recursive/file.txt");
let result = io::create_empty_file("./target/_duckscript/rm/recursive/file.txt");
assert!(result.is_ok());
assert!(path.exists());

test::run_script_and_validate(
vec![create("")],
"out = rm -r ./target/_duckscript/rm/recursive",
CommandValidation::Match("out".to_string(), "true".to_string()),
);

assert!(!path.exists());
}
2 changes: 1 addition & 1 deletion duckscript_sdk/src/sdk/std/fs/rmdir/help.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ var = rmdir path
```

This command delete the requested empty directory and returns true if successful.<br>
If the path leads to a file or the directory is not empty, this command will fail.
If the path leads to a file or a directory which is not empty, this command will fail.

#### Parameters

Expand Down
16 changes: 11 additions & 5 deletions duckscript_sdk/src/sdk/std/fs/rmdir/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::utils::pckg;
use duckscript::types::command::{Command, CommandResult};
use std::fs;
use std::path::Path;

#[cfg(test)]
#[path = "./mod_test.rs"]
Expand All @@ -27,11 +28,16 @@ impl Command for CommandImpl {
if arguments.is_empty() {
CommandResult::Error("Directory path not provided.".to_string())
} else {
let result = fs::remove_dir(&arguments[0]);

match result {
Ok(_) => CommandResult::Continue(Some("true".to_string())),
Err(error) => CommandResult::Error(error.to_string()),
let path = Path::new(&arguments[0]);
if !path.exists() {
CommandResult::Continue(Some("true".to_string()))
} else {
let result = fs::remove_dir(&arguments[0]);

match result {
Ok(_) => CommandResult::Continue(Some("true".to_string())),
Err(error) => CommandResult::Error(error.to_string()),
}
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion duckscript_sdk/src/sdk/std/fs/rmdir/mod_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ fn run_no_path_provided() {

#[test]
fn run_path_not_exists() {
test::run_script_and_fail(vec![create("")], "rmdir ./target/_duckscript/rmdir/newdir");
test::run_script_and_validate(
vec![create("")],
"out = rmdir ./target/_duckscript/rmdir/newdir",
CommandValidation::Match("out".to_string(), "true".to_string()),
);
}

#[test]
Expand Down
33 changes: 33 additions & 0 deletions duckscript_sdk/src/utils/flags.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#[cfg(test)]
#[path = "./flags_test.rs"]
mod flags_test;

pub(crate) fn is_unix_flags_argument(argument: &str) -> bool {
if argument.is_empty() {
false
} else if argument.starts_with("-") && argument.len() > 1 {
let argument_string = argument.to_string();
let chars = argument_string[1..].chars();

for letter in chars {
if !letter.is_ascii_alphabetic() {
return false;
}
}

true
} else {
false
}
}

pub(crate) fn is_unix_flag_exists(flag: char, flags: &str) -> bool {
if !is_unix_flags_argument(flags) {
false
} else {
let lowercase_flags = flags[1..].to_lowercase();
let lowercase_flag = flag.to_string().to_lowercase();

lowercase_flags.contains(&lowercase_flag)
}
}
64 changes: 64 additions & 0 deletions duckscript_sdk/src/utils/flags_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use super::*;

#[test]
fn is_unix_flags_argument_empty() {
let output = is_unix_flags_argument("");

assert!(!output);
}

#[test]
fn is_unix_flags_argument_no_flag_prefix() {
let output = is_unix_flags_argument("abc");

assert!(!output);
}

#[test]
fn is_unix_flags_argument_double_flag_prefix() {
let output = is_unix_flags_argument("--abc");

assert!(!output);
}

#[test]
fn is_unix_flags_argument_valid() {
let output = is_unix_flags_argument("-abc");

assert!(output);
}

#[test]
fn is_unix_flag_exists_empty() {
let output = is_unix_flag_exists('a', "");

assert!(!output);
}

#[test]
fn is_unix_flag_exists_not_flags() {
let output = is_unix_flag_exists('a', "abc");

assert!(!output);
}

#[test]
fn is_unix_flag_exists_not_found() {
let output = is_unix_flag_exists('r', "abc");

assert!(!output);
}

#[test]
fn is_unix_flag_exists_found() {
let output = is_unix_flag_exists('r', "arbc");

assert!(!output);
}

#[test]
fn is_unix_flag_exists_found_different_case() {
let output = is_unix_flag_exists('R', "arbc");

assert!(!output);
}
1 change: 1 addition & 0 deletions duckscript_sdk/src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub(crate) mod condition;
pub(crate) mod eval;
pub(crate) mod flags;
pub(crate) mod instruction_query;
pub(crate) mod io;
pub(crate) mod pckg;
Expand Down

0 comments on commit a18ae71

Please sign in to comment.