touch: support multiple arguments (#2386)

Fixes #2384
This commit is contained in:
Jörn Zaefferer 2020-08-22 02:08:30 +02:00 committed by GitHub
parent 11352f87f0
commit ee26590011
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 65 additions and 22 deletions

View file

@ -10,7 +10,8 @@ pub struct Touch;
#[derive(Deserialize)]
pub struct TouchArgs {
pub target: Tagged<PathBuf>,
target: Tagged<PathBuf>,
rest: Vec<Tagged<PathBuf>>,
}
#[async_trait]
@ -19,14 +20,16 @@ impl WholeStreamCommand for Touch {
"touch"
}
fn signature(&self) -> Signature {
Signature::build("touch").required(
"filename",
SyntaxShape::Path,
"the path of the file you want to create",
)
Signature::build("touch")
.required(
"filename",
SyntaxShape::Path,
"the path of the file you want to create",
)
.rest(SyntaxShape::Path, "additional files to create")
}
fn usage(&self) -> &str {
"creates a file"
"creates one or more files"
}
async fn run(
&self,
@ -37,26 +40,39 @@ impl WholeStreamCommand for Touch {
}
fn examples(&self) -> Vec<Example> {
vec![Example {
description: "Creates \"fixture.json\"",
example: "touch fixture.json",
result: None,
}]
vec![
Example {
description: "Creates \"fixture.json\"",
example: "touch fixture.json",
result: None,
},
Example {
description: "Creates files a, b and c",
example: "touch a b c",
result: None,
},
]
}
}
async fn touch(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let registry = registry.clone();
let (TouchArgs { target }, _) = args.process(&registry).await?;
let (TouchArgs { target, rest }, _) = args.process(&registry).await?;
match OpenOptions::new().write(true).create(true).open(&target) {
Ok(_) => Ok(OutputStream::empty()),
Err(err) => Err(ShellError::labeled_error(
"File Error",
err.to_string(),
&target.tag,
)),
for item in vec![target].into_iter().chain(rest.into_iter()) {
match OpenOptions::new().write(true).create(true).open(&item) {
Ok(_) => continue,
Err(err) => {
return Err(ShellError::labeled_error(
"File Error",
err.to_string(),
&item.tag,
))
}
}
}
Ok(OutputStream::empty())
}
#[cfg(test)]

View file

@ -10,7 +10,22 @@ fn creates_a_file_when_it_doesnt_exist() {
);
let path = dirs.test().join("i_will_be_created.txt");
assert!(path.exists());
})
}
#[test]
fn creates_two_files() {
Playground::setup("create_test_2", |dirs, _sandbox| {
nu!(
cwd: dirs.test(),
"touch a b"
);
let path = dirs.test().join("a");
assert!(path.exists());
let path2 = dirs.test().join("b");
assert!(path2.exists());
})
}

View file

@ -1,6 +1,6 @@
# touch
Create a file in the current or an already existent directory.
Create one or more files in the current or an already existent directory.
It has no effect on existing files.
Unlike GNU touch, the access time and the modified time are not updated.
@ -41,3 +41,15 @@ Create a file within an already existent folder.
modified │ 0 secs ago
──────────┴───────────
```
Create three files at oince
```shell
> touch a b c
> ls
────┬────────────────────┬──────┬──────────┬──────────────
# │ name │ type │ size │ modified
────┼────────────────────┼──────┼──────────┼──────────────
0 │ a │ File │ 0 B │ 0 sec ago
1 │ b │ File │ 0 B │ 0 sec ago
2 │ c │ File │ 0 B │ 0 sec ago
────┴────────────────────┴──────┴──────────┴──────────────