summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeon Schuermann <leon@is.currently.online>2019-09-14 19:02:17 +0200
committerMatthias Beyer <mail@beyermatthias.de>2019-10-26 14:41:31 +0200
commit82e209bea80301c1d2a196902be60ea002fddae3 (patch)
treee4811326c180def9afc93208782125f20f6cc800
parente840d4502c54599fb66991d31dc4c1c74ed7c197 (diff)
downloadimag-82e209bea80301c1d2a196902be60ea002fddae3.zip
imag-82e209bea80301c1d2a196902be60ea002fddae3.tar.gz
Introduce CLI completion support
This is yet another attempt to bring CLI completion to this workspace project. It uses the subcommand-libraries implementing the ImagApplication trait to expose the clap CLI interface. This way, no file import magic happens, it's all just regular dependencies, which should also work with a regular `cargo install`. Signed-off-by: Leon Schuermann <leon@is.currently.online>
-rw-r--r--bin/core/imag/Cargo.toml77
-rw-r--r--bin/core/imag/build.rs156
2 files changed, 233 insertions, 0 deletions
diff --git a/bin/core/imag/Cargo.toml b/bin/core/imag/Cargo.toml
index c3a6df6..904eaac 100644
--- a/bin/core/imag/Cargo.toml
+++ b/bin/core/imag/Cargo.toml
@@ -23,6 +23,31 @@ libimagutil = { version = "0.10.0", path = "../../../lib/etc/libimagutil" }
failure = "0.1.5"
log = "0.4.6"
+# Build time dependencies for cli completion
+imag-annotate = { optional = true, path = "../imag-annotate" }
+imag-diagnostics = { optional = true, path = "../imag-diagnostics" }
+imag-edit = { optional = true, path = "../imag-edit" }
+imag-gps = { optional = true, path = "../imag-gps" }
+imag-grep = { optional = true, path = "../imag-grep" }
+imag-ids = { optional = true, path = "../imag-ids" }
+imag-init = { optional = true, path = "../imag-init" }
+imag-link = { optional = true, path = "../imag-link" }
+imag-mv = { optional = true, path = "../imag-mv" }
+imag-ref = { optional = true, path = "../imag-ref" }
+imag-store = { optional = true, path = "../imag-store" }
+imag-tag = { optional = true, path = "../imag-tag" }
+imag-view = { optional = true, path = "../imag-view" }
+imag-bookmark = { optional = true, path = "../../domain/imag-bookmark" }
+imag-contact = { optional = true, path = "../../domain/imag-contact" }
+imag-diary = { optional = true, path = "../../domain/imag-diary" }
+imag-habit = { optional = true, path = "../../domain/imag-habit" }
+imag-log = { optional = true, path = "../../domain/imag-log" }
+imag-mail = { optional = true, path = "../../domain/imag-mail" }
+imag-notes = { optional = true, path = "../../domain/imag-notes" }
+imag-timetrack = { optional = true, path = "../../domain/imag-timetrack" }
+imag-todo = { optional = true, path = "../../domain/imag-todo" }
+imag-wiki = { optional = true, path = "../../domain/imag-wiki" }
+
[badges]
travis-ci = { repository = "matthiasbeyer/imag" }
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
@@ -48,3 +73,55 @@ version = "0.10.0"
path = "../../../lib/core/libimagrt"
features = ["pub_logging_initialization"]
+[features]
+default = [ "cc-all" ]
+
+# Features for enabling cli completion files for individual subcommands
+cc-all = [
+ "cc-imag-annotate",
+ "cc-imag-diagnostics",
+ "cc-imag-edit",
+ "cc-imag-gps",
+ "cc-imag-grep",
+ "cc-imag-ids",
+ "cc-imag-init",
+ "cc-imag-link",
+ "cc-imag-mv",
+ "cc-imag-ref",
+ "cc-imag-store",
+ "cc-imag-tag",
+ "cc-imag-view",
+ "cc-imag-bookmark",
+ "cc-imag-contact",
+ "cc-imag-diary",
+ "cc-imag-habit",
+ "cc-imag-log",
+ "cc-imag-mail",
+ "cc-imag-notes",
+ "cc-imag-timetrack",
+ "cc-imag-todo",
+ "cc-imag-wiki",
+]
+cc-imag-annotate = [ "imag-annotate" ]
+cc-imag-diagnostics = [ "imag-diagnostics" ]
+cc-imag-edit = [ "imag-edit" ]
+cc-imag-gps = [ "imag-gps" ]
+cc-imag-grep = [ "imag-grep" ]
+cc-imag-ids = [ "imag-ids" ]
+cc-imag-init = [ "imag-init" ]
+cc-imag-link = [ "imag-link" ]
+cc-imag-mv = [ "imag-mv" ]
+cc-imag-ref = [ "imag-ref" ]
+cc-imag-store = [ "imag-store" ]
+cc-imag-tag = [ "imag-tag" ]
+cc-imag-view = [ "imag-view" ]
+cc-imag-bookmark = [ "imag-bookmark" ]
+cc-imag-contact = [ "imag-contact" ]
+cc-imag-diary = [ "imag-diary" ]
+cc-imag-habit = [ "imag-habit" ]
+cc-imag-log = [ "imag-log" ]
+cc-imag-mail = [ "imag-mail" ]
+cc-imag-notes = [ "imag-notes" ]
+cc-imag-timetrack = [ "imag-timetrack" ]
+cc-imag-todo = [ "imag-todo" ]
+cc-imag-wiki = [ "imag-wiki" ] \ No newline at end of file
diff --git a/bin/core/imag/build.rs b/bin/core/imag/build.rs
new file mode 100644
index 0000000..c51ee54
--- /dev/null
+++ b/bin/core/imag/build.rs
@@ -0,0 +1,156 @@
+//
+// imag - the personal information management suite for the commandline
+// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; version
+// 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+extern crate clap;
+extern crate libimagrt;
+extern crate libimagentrytag;
+extern crate libimagutil;
+
+use clap::Shell;
+use libimagrt::runtime::Runtime;
+
+#[allow(unused_imports)]
+use libimagrt::application::ImagApplication;
+
+#[cfg(feature = "cc-imag-annotate")]
+extern crate libimagannotatecmd;
+#[cfg(feature = "cc-imag-diagnostics")]
+extern crate libimagdiagnosticscmd;
+#[cfg(feature = "cc-imag-edit")]
+extern crate libimageditcmd;
+#[cfg(feature = "cc-imag-gps")]
+extern crate libimaggpscmd;
+#[cfg(feature = "cc-imag-grep")]
+extern crate libimaggrepcmd;
+#[cfg(feature = "cc-imag-ids")]
+extern crate libimagidscmd;
+#[cfg(feature = "cc-imag-init")]
+extern crate libimaginitcmd;
+#[cfg(feature = "cc-imag-link")]
+extern crate libimaglinkcmd;
+#[cfg(feature = "cc-imag-mv")]
+extern crate libimagmvcmd;
+#[cfg(feature = "cc-imag-ref")]
+extern crate libimagrefcmd;
+#[cfg(feature = "cc-imag-store")]
+extern crate libimagstorecmd;
+#[cfg(feature = "cc-imag-tag")]
+extern crate libimagtagcmd;
+#[cfg(feature = "cc-imag-view")]
+extern crate libimagviewcmd;
+#[cfg(feature = "cc-imag-bookmark")]
+extern crate libimagbookmarkfrontend;
+#[cfg(feature = "cc-imag-contact")]
+extern crate libimagcontactfrontend;
+#[cfg(feature = "cc-imag-diary")]
+extern crate libimagdiaryfrontend;
+#[cfg(feature = "cc-imag-habit")]
+extern crate libimaghabitfrontend;
+#[cfg(feature = "cc-imag-log")]
+extern crate libimaglogfrontend;
+#[cfg(feature = "cc-imag-mail")]
+extern crate libimagmailfrontend;
+#[cfg(feature = "cc-imag-notes")]
+extern crate libimagnotesfrontend;
+#[cfg(feature = "cc-imag-timetrack")]
+extern crate libimagtimetrackfrontend;
+#[cfg(feature = "cc-imag-todo")]
+extern crate libimagtodofrontend;
+
+/// This macro reduces boilerplate code.
+///
+/// For example: `build_subcommand!("counter", libbinimagcounter, ImagCounter)`
+/// will result in the following code:
+/// ```ignore
+/// ImagCounter::build_cli(Runtime::get_default_cli_builder(
+/// "counter",
+/// "abc",
+/// "counter"))
+/// ```
+/// As for the `"abc"` part, it does not matter
+/// which version the subcommand is getting here, as the
+/// output of this script is a completion script, which
+/// does not contain information about the version at all.
+#[allow(unused_macros)]
+macro_rules! build_subcommand {
+ ($name:expr, $lib:ident, $implementor:ident) => (
+ $lib::$implementor::build_cli(Runtime::get_default_cli_builder($name, "abc", $name))
+ )
+}
+
+fn main() {
+ // Make the `imag`-App...
+ let app = Runtime::get_default_cli_builder(
+ "imag",
+ "abc",
+ "imag");
+
+ // and add all the subapps as subcommands.
+ // TODO: This feels tedious, can we automate this?
+ #[cfg(feature = "cc-imag-annotate")]
+ let app = app.subcommand(build_subcommand!("annotate", libimagannotatecmd, ImagAnnotate));
+ #[cfg(feature = "cc-imag-diagnostics")]
+ let app = app.subcommand(build_subcommand!("diagnostics", libimagdiagnosticscmd, ImagDiagnostics));
+ #[cfg(feature = "cc-imag-edit")]
+ let app = app.subcommand(build_subcommand!("edit", libimageditcmd, ImagEdit));
+ #[cfg(feature = "cc-imag-gps")]
+ let app = app.subcommand(build_subcommand!("gps", libimaggpscmd, ImagGps));
+ #[cfg(feature = "cc-imag-grep")]
+ let app = app.subcommand(build_subcommand!("grep", libimaggrepcmd, ImagGrep));
+ #[cfg(feature = "cc-imag-ids")]
+ let app = app.subcommand(build_subcommand!("ids", libimagidscmd, ImagIds));
+ #[cfg(feature = "cc-imag-init")]
+ let app = app.subcommand(build_subcommand!("init", libimaginitcmd, ImagInit));
+ #[cfg(feature = "cc-imag-link")]
+ let app = app.subcommand(build_subcommand!("link", libimaglinkcmd, ImagLink));
+ #[cfg(feature = "cc-imag-mv")]
+ let app = app.subcommand(build_subcommand!("mv", libimagmvcmd, ImagMv));
+ #[cfg(feature = "cc-imag-ref")]
+ let app = app.subcommand(build_subcommand!("ref", libimagrefcmd, ImagRef));
+ #[cfg(feature = "cc-imag-store")]
+ let app = app.subcommand(build_subcommand!("store", libimagstorecmd, ImagStore));
+ #[cfg(feature = "cc-imag-tag")]
+ let app = app.subcommand(build_subcommand!("tag", libimagtagcmd, ImagTag));
+ #[cfg(feature = "cc-imag-view")]
+ let app = app.subcommand(build_subcommand!("view", libimagviewcmd, ImagView));
+ #[cfg(feature = "cc-imag-bookmark")]
+ let app = app.subcommand(build_subcommand!("bookmark", libimagbookmarkfrontend, ImagBookmark));
+ #[cfg(feature = "cc-imag-contact")]
+ let app = app.subcommand(build_subcommand!("contact", libimagcontactfrontend, ImagContact));
+ #[cfg(feature = "cc-imag-diary")]
+ let app = app.subcommand(build_subcommand!("diary", libimagdiaryfrontend, ImagDiary));
+ #[cfg(feature = "cc-imag-habit")]
+ let app = app.subcommand(build_subcommand!("habit", libimaghabitfrontend, ImagHabit));
+ #[cfg(feature = "cc-imag-log")]
+ let app = app.subcommand(build_subcommand!("log", libimaglogfrontend, ImagLog));
+ #[cfg(feature = "cc-imag-mail")]
+ let app = app.subcommand(build_subcommand!("mail", libimagmailfrontend, ImagMail));
+ #[cfg(feature = "cc-imag-notes")]
+ let app = app.subcommand(build_subcommand!("notes", libimagnotesfrontend, ImagNotes));
+ #[cfg(feature = "cc-imag-timetrack")]
+ let app = app.subcommand(build_subcommand!("timetrack", libimagtimetrackfrontend, ImagTimetrack));
+ #[cfg(feature = "cc-imag-todo")]
+ let app = app.subcommand(build_subcommand!("todo", libimagtodofrontend, ImagTodo));
+
+ let mut app = app;
+ // Actually generates the completion files
+ app.gen_completions("imag", Shell::Bash, "../../../target/");
+ app.gen_completions("imag", Shell::Fish, "../../../target/");
+ app.gen_completions("imag", Shell::Zsh, "../../../target/");
+}