New glob_array command #90

This commit is contained in:
sagie gur ari 2020-03-07 17:52:23 +00:00
parent 41050d6193
commit bbf2a6ebda
8 changed files with 326 additions and 1 deletions

View file

@ -2,6 +2,7 @@
### v0.2.2
* New glob_array command #90
* New chmod command #19
* New is_readonly command.
* New is_path_exists command.

View file

@ -61,6 +61,7 @@
* [std::fs::GetCanonicalPath (canonicalize)](#std__fs__GetCanonicalPath)
* [std::fs::GetFileName (basename)](#std__fs__GetFileName)
* [std::fs::GetParentDirectory (dirname)](#std__fs__GetParentDirectory)
* [std::fs::GlobArray (glob_array, globarray)](#std__fs__GlobArray)
* [std::fs::IsDirectory (is_directory, is_dir)](#std__fs__IsDirectory)
* [std::fs::IsFile (is_file)](#std__fs__IsFile)
* [std::fs::IsReadonly (is_readonly)](#std__fs__IsReadonly)
@ -2342,6 +2343,37 @@ directory = dirname ./dir/file.txt
#### Aliases:
dirname
<a name="std__fs__GlobArray"></a>
## std::fs::GlobArray
```sh
handle = glob_array pattern
```
Returns an array handle containing all path entries found from the provided glob pattern.<br>
The pattern can be a relative path from current directory or an absolute path.
#### Parameters
The glob pattern.
#### Return Value
The array handle.
#### Examples
```sh
handle = glob_array ./somedir/**/*.txt
for path in ${handle}
echo ${path}
end
```
#### Aliases:
glob_array, globarray
<a name="std__fs__IsDirectory"></a>
## std::fs::IsDirectory
```sh

View file

@ -25,10 +25,11 @@ include = [
[dependencies]
attohttpc = "^0.11"
base64 = "^0.11"
cfg-if = "^0.1.10"
cfg-if = "^0.1"
duckscript = { version = "^0.2.1", path = "../duckscript" }
fs_extra = "^1"
fsio = { version = "^0.1", features = ["temp-path"] }
glob = "^0.3"
home = "^0.5"
java-properties = "^1"
meval = "^0.2"

View file

@ -0,0 +1,24 @@
```sh
handle = glob_array pattern
```
Returns an array handle containing all path entries found from the provided glob pattern.<br>
The pattern can be a relative path from current directory or an absolute path.
#### Parameters
The glob pattern.
#### Return Value
The array handle.
#### Examples
```sh
handle = glob_array ./somedir/**/*.txt
for path in ${handle}
echo ${path}
end
```

View file

@ -0,0 +1,83 @@
use crate::utils::pckg;
use crate::utils::state::put_handle;
use duckscript::types::command::{Command, CommandResult, Commands};
use duckscript::types::instruction::Instruction;
use duckscript::types::runtime::StateValue;
use fsio::path::from_path::FromPath;
use glob::glob;
use std::collections::HashMap;
#[cfg(test)]
#[path = "./mod_test.rs"]
mod mod_test;
#[derive(Clone)]
pub(crate) struct CommandImpl {
package: String,
}
impl Command for CommandImpl {
fn name(&self) -> String {
pckg::concat(&self.package, "GlobArray")
}
fn aliases(&self) -> Vec<String> {
vec!["glob_array".to_string(), "globarray".to_string()]
}
fn help(&self) -> String {
include_str!("help.md").to_string()
}
fn clone_and_box(&self) -> Box<dyn Command> {
Box::new((*self).clone())
}
fn requires_context(&self) -> bool {
true
}
fn run_with_context(
&self,
arguments: Vec<String>,
state: &mut HashMap<String, StateValue>,
_variables: &mut HashMap<String, String>,
_output_variable: Option<String>,
_instructions: &Vec<Instruction>,
_commands: &mut Commands,
_line: usize,
) -> CommandResult {
if arguments.is_empty() {
CommandResult::Error("Glob pattern not provided.".to_string())
} else {
match glob(&arguments[0]) {
Ok(paths) => {
let mut array = vec![];
for entry in paths {
match entry {
Ok(path) => {
let value_string: String = FromPath::from_path(&path);
let state_value = StateValue::String(value_string);
array.push(state_value);
}
Err(error) => return CommandResult::Error(error.to_string()),
}
}
let key = put_handle(state, StateValue::List(array));
CommandResult::Continue(Some(key))
}
Err(error) => CommandResult::Error(error.to_string()),
}
}
}
}
pub(crate) fn create(package: &str) -> Box<dyn Command> {
Box::new(CommandImpl {
package: package.to_string(),
})
}

View file

@ -0,0 +1,99 @@
use super::*;
use crate::test;
use crate::test::CommandValidation;
use crate::utils::state::get_handles_sub_state;
#[test]
fn common_functions() {
test::test_common_command_functions(create(""));
}
#[test]
fn run_no_pattern_provided() {
test::run_script_and_error(vec![create("")], "out = glob_array", "out");
}
#[test]
fn run_results_found() {
let mut result = fsio::directory::create("./target/_duckscript/glob/1/dir1/dir12");
assert!(result.is_ok());
result = fsio::directory::create("./target/_duckscript/glob/1/dir2");
assert!(result.is_ok());
result = fsio::directory::create("./target/_duckscript/glob/1/dir3/file.txt");
assert!(result.is_ok());
let mut context = test::run_script_and_validate(
vec![create("")],
r#"out = glob_array ./target/_duckscript/glob/1/**/*"#,
CommandValidation::Contains("out".to_string(), "handle:".to_string()),
);
let state = get_handles_sub_state(&mut context.state);
let list_value = state.remove(context.variables.get("out").unwrap()).unwrap();
match list_value {
StateValue::List(list) => {
assert_eq!(list.len(), 5);
let mut paths = vec![];
for entry in list {
match entry {
StateValue::String(value) => paths.push(value.replace("\\", "/")),
_ => panic!("Invalid handle value."),
};
}
paths.sort();
assert_eq!(
paths,
vec![
"target/_duckscript/glob/1/dir1",
"target/_duckscript/glob/1/dir1/dir12",
"target/_duckscript/glob/1/dir2",
"target/_duckscript/glob/1/dir3",
"target/_duckscript/glob/1/dir3/file.txt"
]
);
}
_ => panic!("Invalid handle type."),
}
}
#[test]
fn run_results_partial_found() {
let mut result = fsio::directory::create("./target/_duckscript/glob/2/dir1/dir12");
assert!(result.is_ok());
result = fsio::directory::create("./target/_duckscript/glob/2/dir2");
assert!(result.is_ok());
result = fsio::directory::create("./target/_duckscript/glob/2/dir3/file.txt");
assert!(result.is_ok());
let mut context = test::run_script_and_validate(
vec![create("")],
r#"out = glob_array ./target/_duckscript/glob/2/**/*.txt"#,
CommandValidation::Contains("out".to_string(), "handle:".to_string()),
);
let state = get_handles_sub_state(&mut context.state);
let list_value = state.remove(context.variables.get("out").unwrap()).unwrap();
match list_value {
StateValue::List(list) => {
assert_eq!(list.len(), 1);
let mut paths = vec![];
for entry in list {
match entry {
StateValue::String(value) => paths.push(value.replace("\\", "/")),
_ => panic!("Invalid handle value."),
};
}
paths.sort();
assert_eq!(paths, vec!["target/_duckscript/glob/2/dir3/file.txt"]);
}
_ => panic!("Invalid handle type."),
}
}

View file

@ -4,6 +4,7 @@ mod canonical;
mod cp;
mod dirname;
mod exists;
mod glob_array;
mod is_directory;
mod is_file;
mod is_readonly;
@ -36,6 +37,7 @@ pub(crate) fn load(commands: &mut Commands, parent: &str) -> Result<(), ScriptEr
commands.set(cp::create(&package))?;
commands.set(dirname::create(&package))?;
commands.set(exists::create(&package))?;
commands.set(glob_array::create(&package))?;
commands.set(is_directory::create(&package))?;
commands.set(is_file::create(&package))?;
commands.set(is_readonly::create(&package))?;

View file

@ -0,0 +1,83 @@
fn test_found_all
mkdir ./target/_duckscript/glob/test_found_all/dir1/dir12
mkdir ./target/_duckscript/glob/test_found_all/dir2
mkdir ./target/_duckscript/glob/test_found_all/dir3/file.txt
handle = glob_array ./target/_duckscript/glob/test_found_all/**/*
size = array_length ${handle}
assert_eq ${size} 5
expected = map
map_put ${expected} target/_duckscript/glob/test_found_all/dir1 true
map_put ${expected} target/_duckscript/glob/test_found_all/dir1/dir12 true
map_put ${expected} target/_duckscript/glob/test_found_all/dir2 true
map_put ${expected} target/_duckscript/glob/test_found_all/dir3 true
map_put ${expected} target/_duckscript/glob/test_found_all/dir3/file.txt true
size = map_size ${expected}
assert_eq ${size} 5
for path in ${handle}
map_remove ${expected} ${path}
end
size = map_size ${expected}
assert_eq ${size} 0
release ${expected}
release ${handle}
end
fn test_found_file_only
mkdir ./target/_duckscript/glob/test_found_file_only/dir1/dir12
mkdir ./target/_duckscript/glob/test_found_file_only/dir2
mkdir ./target/_duckscript/glob/test_found_file_only/dir3/file.txt
handle = glob_array ./target/_duckscript/glob/test_found_file_only/**/*.txt
size = array_length ${handle}
assert_eq ${size} 1
expected = map
map_put ${expected} target/_duckscript/glob/test_found_file_only/dir3/file.txt true
size = map_size ${expected}
assert_eq ${size} 1
for path in ${handle}
map_remove ${expected} ${path}
end
size = map_size ${expected}
assert_eq ${size} 0
release ${expected}
release ${handle}
end
fn test_found_sub_tree
mkdir ./target/_duckscript/glob/test_found_sub_tree/dir1/dir12
mkdir ./target/_duckscript/glob/test_found_sub_tree/dir2
mkdir ./target/_duckscript/glob/test_found_sub_tree/dir3/dir31/file.txt
handle = glob_array ./target/_duckscript/glob/test_found_sub_tree/dir3/**/*
size = array_length ${handle}
assert_eq ${size} 2
expected = map
map_put ${expected} target/_duckscript/glob/test_found_sub_tree/dir3/dir31 true
map_put ${expected} target/_duckscript/glob/test_found_sub_tree/dir3/dir31/file.txt true
size = map_size ${expected}
assert_eq ${size} 2
for path in ${handle}
map_remove ${expected} ${path}
end
size = map_size ${expected}
assert_eq ${size} 0
release ${expected}
release ${handle}
end