Merge pull request #1343 from matthiasbeyer/imag-tag/rewrite-cli
imag-tag: rewrite cli
This commit is contained in:
commit
ee72e61b44
3 changed files with 61 additions and 97 deletions
|
@ -67,27 +67,30 @@ fn main() {
|
||||||
"Direct interface to the store. Use with great care!",
|
"Direct interface to the store. Use with great care!",
|
||||||
build_ui);
|
build_ui);
|
||||||
|
|
||||||
let id = rt.cli().value_of("id").unwrap(); // enforced by clap
|
let id = rt.cli().value_of("id").map(PathBuf::from).unwrap(); // enforced by clap
|
||||||
rt.cli()
|
rt.cli()
|
||||||
.subcommand_name()
|
.subcommand_name()
|
||||||
.map_or_else(
|
.map(|name| match name {
|
||||||
|| {
|
"list" => list(id, &rt),
|
||||||
|
"remove" => {
|
||||||
let id = PathBuf::from(id);
|
let id = PathBuf::from(id);
|
||||||
let add = get_add_tags(rt.cli());
|
let add = None;
|
||||||
let rem = get_remove_tags(rt.cli());
|
let rem = get_remove_tags(rt.cli());
|
||||||
|
debug!("id = {:?}, add = {:?}, rem = {:?}", id, add, rem);
|
||||||
alter(&rt, id, add, rem);
|
alter(&rt, id, add, rem);
|
||||||
},
|
},
|
||||||
|name| {
|
"add" => {
|
||||||
let id = PathBuf::from(id);
|
let id = PathBuf::from(id);
|
||||||
debug!("Call: {}", name);
|
let add = get_add_tags(rt.cli());
|
||||||
match name {
|
let rem = None;
|
||||||
"list" => list(id, &rt),
|
debug!("id = {:?}, add = {:?}, rem = {:?}", id, add, rem);
|
||||||
_ => {
|
alter(&rt, id, add, rem);
|
||||||
warn!("Unknown command");
|
},
|
||||||
// More error handling
|
_ => {
|
||||||
},
|
error!("Unknown command");
|
||||||
};
|
::std::process::exit(1)
|
||||||
});
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alter(rt: &Runtime, id: PathBuf, add: Option<Vec<Tag>>, rem: Option<Vec<Tag>>) {
|
fn alter(rt: &Runtime, id: PathBuf, add: Option<Vec<Tag>>, rem: Option<Vec<Tag>>) {
|
||||||
|
@ -190,36 +193,28 @@ fn list(id: PathBuf, rt: &Runtime) {
|
||||||
///
|
///
|
||||||
/// Returns none if the argument was not specified
|
/// Returns none if the argument was not specified
|
||||||
fn get_add_tags(matches: &ArgMatches) -> Option<Vec<Tag>> {
|
fn get_add_tags(matches: &ArgMatches) -> Option<Vec<Tag>> {
|
||||||
let a = "add-tags";
|
retrieve_tags(matches, "add", "add-tags")
|
||||||
extract_tags(matches, a, '+')
|
|
||||||
.or_else(|| matches.values_of(a).map(|values| values.map(String::from).collect()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the tags which should be removed from the commandline
|
/// Get the tags which should be removed from the commandline
|
||||||
///
|
///
|
||||||
/// Returns none if the argument was not specified
|
/// Returns none if the argument was not specified
|
||||||
fn get_remove_tags(matches: &ArgMatches) -> Option<Vec<Tag>> {
|
fn get_remove_tags(matches: &ArgMatches) -> Option<Vec<Tag>> {
|
||||||
let r = "remove-tags";
|
retrieve_tags(matches, "remove", "remove-tags")
|
||||||
extract_tags(matches, r, '+')
|
|
||||||
.or_else(|| matches.values_of(r).map(|values| values.map(String::from).collect()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_tags(matches: &ArgMatches, specifier: &str, specchar: char) -> Option<Vec<Tag>> {
|
fn retrieve_tags(m: &ArgMatches, s: &'static str, v: &'static str) -> Option<Vec<Tag>> {
|
||||||
if let Some(submatch) = matches.subcommand_matches("tags") {
|
Some(m
|
||||||
submatch.values_of(specifier)
|
.subcommand_matches(s)
|
||||||
.map(|values| values.map(String::from).collect())
|
.unwrap_or_else(|| {
|
||||||
} else {
|
error!("Expected subcommand '{}', but was not specified", s);
|
||||||
matches.values_of("specify-tags")
|
::std::process::exit(1)
|
||||||
.map(|argmatches| {
|
})
|
||||||
argmatches
|
.values_of(v)
|
||||||
.map(String::from)
|
.unwrap() // enforced by clap
|
||||||
.filter(|s| s.starts_with(specchar))
|
.into_iter()
|
||||||
.map(|s| {
|
.map(String::from)
|
||||||
String::from(s.split_at(1).1)
|
.collect())
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -275,7 +270,7 @@ mod tests {
|
||||||
setup_logging();
|
setup_logging();
|
||||||
debug!("Generating runtime");
|
debug!("Generating runtime");
|
||||||
let name = "test-tag-add-adds-tags";
|
let name = "test-tag-add-adds-tags";
|
||||||
let rt = generate_test_runtime(vec![name, "--add", "foo"]).unwrap();
|
let rt = generate_test_runtime(vec![name, "add", "foo"]).unwrap();
|
||||||
|
|
||||||
debug!("Creating default entry");
|
debug!("Creating default entry");
|
||||||
create_test_default_entry(&rt, name).unwrap();
|
create_test_default_entry(&rt, name).unwrap();
|
||||||
|
@ -285,12 +280,8 @@ mod tests {
|
||||||
let add = get_add_tags(rt.cli());
|
let add = get_add_tags(rt.cli());
|
||||||
debug!("Add-tags: {:?}", add);
|
debug!("Add-tags: {:?}", add);
|
||||||
|
|
||||||
debug!("Getting 'remove' tags");
|
|
||||||
let rem = get_remove_tags(rt.cli());
|
|
||||||
debug!("Rem-tags: {:?}", rem);
|
|
||||||
|
|
||||||
debug!("Altering things");
|
debug!("Altering things");
|
||||||
alter(&rt, id.clone(), add, rem);
|
alter(&rt, id.clone(), add, None);
|
||||||
debug!("Altered");
|
debug!("Altered");
|
||||||
|
|
||||||
let test_entry = rt.store().get(id).unwrap().unwrap();
|
let test_entry = rt.store().get(id).unwrap().unwrap();
|
||||||
|
@ -306,48 +297,12 @@ mod tests {
|
||||||
assert_eq!(*test_tags, tags_toml_value(vec!["foo"]));
|
assert_eq!(*test_tags, tags_toml_value(vec!["foo"]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_tag_add_more_than_remove_adds_tags() {
|
|
||||||
setup_logging();
|
|
||||||
debug!("Generating runtime");
|
|
||||||
let name = "test-tag-add-more-than-remove-adds-tags";
|
|
||||||
let rt = generate_test_runtime(vec![name,
|
|
||||||
"--add", "foo",
|
|
||||||
"--add", "bar",
|
|
||||||
"--add", "baz",
|
|
||||||
"--add", "bub",
|
|
||||||
"--remove", "foo",
|
|
||||||
"--remove", "bar",
|
|
||||||
"--remove", "baz",
|
|
||||||
]).unwrap();
|
|
||||||
|
|
||||||
debug!("Creating default entry");
|
|
||||||
create_test_default_entry(&rt, name).unwrap();
|
|
||||||
let id = PathBuf::from(String::from(name));
|
|
||||||
|
|
||||||
// Manually add tags
|
|
||||||
let add = get_add_tags(rt.cli());
|
|
||||||
|
|
||||||
debug!("Getting 'remove' tags");
|
|
||||||
let rem = get_remove_tags(rt.cli());
|
|
||||||
debug!("Rem-tags: {:?}", rem);
|
|
||||||
|
|
||||||
debug!("Altering things");
|
|
||||||
alter(&rt, id.clone(), add, rem);
|
|
||||||
debug!("Altered");
|
|
||||||
|
|
||||||
let test_entry = rt.store().get(id).unwrap().unwrap();
|
|
||||||
let test_tags = get_entry_tags(&test_entry).unwrap().unwrap();
|
|
||||||
|
|
||||||
assert_eq!(*test_tags, tags_toml_value(vec!["bub"]));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_tag_remove_removes_tag() {
|
fn test_tag_remove_removes_tag() {
|
||||||
setup_logging();
|
setup_logging();
|
||||||
debug!("Generating runtime");
|
debug!("Generating runtime");
|
||||||
let name = "test-tag-remove-removes-tag";
|
let name = "test-tag-remove-removes-tag";
|
||||||
let rt = generate_test_runtime(vec![name, "--remove", "foo"]).unwrap();
|
let rt = generate_test_runtime(vec![name, "remove", "foo"]).unwrap();
|
||||||
|
|
||||||
debug!("Creating default entry");
|
debug!("Creating default entry");
|
||||||
create_test_default_entry(&rt, name).unwrap();
|
create_test_default_entry(&rt, name).unwrap();
|
||||||
|
@ -375,7 +330,7 @@ mod tests {
|
||||||
setup_logging();
|
setup_logging();
|
||||||
debug!("Generating runtime");
|
debug!("Generating runtime");
|
||||||
let name = "test-tag-remove-removes-only-to-remove-tag-doesnt-crash-on-nonexistent-tag";
|
let name = "test-tag-remove-removes-only-to-remove-tag-doesnt-crash-on-nonexistent-tag";
|
||||||
let rt = generate_test_runtime(vec![name, "--remove", "foo"]).unwrap();
|
let rt = generate_test_runtime(vec![name, "remove", "foo"]).unwrap();
|
||||||
|
|
||||||
debug!("Creating default entry");
|
debug!("Creating default entry");
|
||||||
create_test_default_entry(&rt, name).unwrap();
|
create_test_default_entry(&rt, name).unwrap();
|
||||||
|
@ -403,7 +358,7 @@ mod tests {
|
||||||
setup_logging();
|
setup_logging();
|
||||||
debug!("Generating runtime");
|
debug!("Generating runtime");
|
||||||
let name = "test-tag-remove-removes-but-doesnt-crash-on-nonexistent-tag";
|
let name = "test-tag-remove-removes-but-doesnt-crash-on-nonexistent-tag";
|
||||||
let rt = generate_test_runtime(vec![name, "--remove", "foo", "--remove", "bar"]).unwrap();
|
let rt = generate_test_runtime(vec![name, "remove", "foo", "bar"]).unwrap();
|
||||||
|
|
||||||
debug!("Creating default entry");
|
debug!("Creating default entry");
|
||||||
create_test_default_entry(&rt, name).unwrap();
|
create_test_default_entry(&rt, name).unwrap();
|
||||||
|
|
|
@ -30,23 +30,31 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
|
||||||
.value_name("ID")
|
.value_name("ID")
|
||||||
.help("Entry to use"))
|
.help("Entry to use"))
|
||||||
|
|
||||||
.arg(Arg::with_name("add-tags")
|
.subcommand(SubCommand::with_name("add")
|
||||||
.short("a")
|
.about("Add tags")
|
||||||
.long("add")
|
.version("0.1")
|
||||||
.takes_value(true)
|
.arg(Arg::with_name("add-tags")
|
||||||
.value_name("tags")
|
.index(1)
|
||||||
.multiple(true)
|
.takes_value(true)
|
||||||
.validator(is_tag)
|
.required(true)
|
||||||
.help("Add these tags"))
|
.multiple(true)
|
||||||
|
.value_name("tags")
|
||||||
|
.validator(is_tag)
|
||||||
|
.help("Add these tags"))
|
||||||
|
)
|
||||||
|
|
||||||
.arg(Arg::with_name("remove-tags")
|
.subcommand(SubCommand::with_name("remove")
|
||||||
.short("r")
|
.about("Remove tags")
|
||||||
.long("remove")
|
.version("0.1")
|
||||||
.takes_value(true)
|
.arg(Arg::with_name("remove-tags")
|
||||||
.multiple(true)
|
.index(1)
|
||||||
.validator(is_tag)
|
.takes_value(true)
|
||||||
.value_name("tags")
|
.required(true)
|
||||||
.help("Remove these tags"))
|
.multiple(true)
|
||||||
|
.value_name("tags")
|
||||||
|
.validator(is_tag)
|
||||||
|
.help("Remove these tags"))
|
||||||
|
)
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("list")
|
.subcommand(SubCommand::with_name("list")
|
||||||
.about("List tags (default)")
|
.about("List tags (default)")
|
||||||
|
|
|
@ -56,6 +56,7 @@ This section contains the changelog from the last release to the next release.
|
||||||
"debug" mode.
|
"debug" mode.
|
||||||
* `imag-diary` supports "daily" diaries now.
|
* `imag-diary` supports "daily" diaries now.
|
||||||
* `imag-contact` joins multiple emails with "," now
|
* `imag-contact` joins multiple emails with "," now
|
||||||
|
* `imag-tag` commandline was rewritten for positional arguments.
|
||||||
* Bugfixes
|
* Bugfixes
|
||||||
* imag does not panic anymore when piping and breaking that pipe, for
|
* imag does not panic anymore when piping and breaking that pipe, for
|
||||||
example like with `imag store ids | head -n 1`.
|
example like with `imag store ids | head -n 1`.
|
||||||
|
|
Loading…
Reference in a new issue