diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2018-04-19 22:40:31 +0200 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2018-04-24 13:56:11 +0200 |
commit | 055a55c9f088dd2cfaac0e2d9e45056fe902df8f (patch) | |
tree | 1f4c8977230319e68c2647021641d28be5843c1f | |
parent | cbdfb02423fb19ab5740e335e24a585d8937095d (diff) |
Add imag-git command
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | bin/core/imag-git/Cargo.toml | 36 | ||||
-rw-r--r-- | bin/core/imag-git/src/main.rs | 170 | ||||
-rw-r--r-- | bin/core/imag-git/src/ui.rs | 26 | ||||
-rw-r--r-- | imagrc.toml | 7 |
5 files changed, 240 insertions, 0 deletions
@@ -4,6 +4,7 @@ members = [ "bin/core/imag-annotate", "bin/core/imag-diagnostics", "bin/core/imag-edit", + "bin/core/imag-git", "bin/core/imag-gps", "bin/core/imag-grep", "bin/core/imag-ids", diff --git a/bin/core/imag-git/Cargo.toml b/bin/core/imag-git/Cargo.toml new file mode 100644 index 00000000..e07b6f22 --- /dev/null +++ b/bin/core/imag-git/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "imag-git" +version = "0.8.0" +authors = ["Matthias Beyer <mail@beyermatthias.de>"] + +description = "Part of the imag core distribution: imag-git command" + +keywords = ["imag", "PIM", "personal", "information", "management"] +readme = "../../../README.md" +license = "LGPL-2.1" + +documentation = "https://imag-pim.org/doc/" +repository = "https://github.com/matthiasbeyer/imag" +homepage = "http://imag-pim.org" + +build = "../../../build.rs" + +[badges] +travis-ci = { repository = "matthiasbeyer/imag" } +is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" } +is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" } +maintenance = { status = "actively-developed" } + +[dependencies] +log = "0.3" +toml = "0.4" +toml-query = "0.6" + +libimagrt = { version = "0.8.0", path = "../../../lib/core/libimagrt" } +libimagerror = { version = "0.8.0", path = "../../../lib/core/libimagerror" } + +[dependencies.clap] +version = "^2.29" +default-features = false +features = ["color", "suggestions", "wrap_help"] + diff --git a/bin/core/imag-git/src/main.rs b/bin/core/imag-git/src/main.rs new file mode 100644 index 00000000..f17cf335 --- /dev/null +++ b/bin/core/imag-git/src/main.rs @@ -0,0 +1,170 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015-2018 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 +// + +#![deny( + non_camel_case_types, + non_snake_case, + path_statements, + trivial_numeric_casts, + unstable_features, + unused_allocation, + unused_import_braces, + unused_imports, + unused_must_use, + unused_mut, + unused_qualifications, + while_true, +)] + +extern crate clap; +#[macro_use] extern crate log; +extern crate toml; +extern crate toml_query; + +#[macro_use] extern crate libimagrt; +extern crate libimagerror; + +use std::io::Write; +use std::io::ErrorKind; +use std::process::Command; + +use toml::Value; +use toml_query::read::TomlValueReadExt; + +use libimagerror::exit::ExitUnwrap; +use libimagerror::io::ToExitCode; +use libimagrt::setup::generate_runtime_setup; + +mod ui; + +fn main() { + let version = make_imag_version!(); + let rt = generate_runtime_setup("imag-git", + &version, + "Helper to call git in the store", + ui::build_ui); + + let execute_in_store = rt + .config() + .unwrap_or_else(|| { + error!("No configuration. Please use git yourself, not via imag-git"); + error!("Won't continue without configuration."); + ::std::process::exit(1); + }) + .read("git.execute_in_store") + .unwrap_or_else(|e| { + error!("Failed to read config setting 'git.execute_in_store'"); + error!("-> {:?}", e); + ::std::process::exit(1) + }) + .unwrap_or_else(|| { + error!("Missing config setting 'git.execute_in_store'"); + ::std::process::exit(1) + }); + + let execute_in_store = match *execute_in_store { + Value::Boolean(b) => b, + _ => { + error!("Type error: 'git.execute_in_store' is not a boolean!"); + ::std::process::exit(1) + } + }; + + let execpath = if execute_in_store { + rt.store().path().to_str() + } else { + rt.rtp().to_str() + } + .map(String::from) + .unwrap_or_else(|| { + error!("Cannot parse to string: {:?}", rt.store().path()); + ::std::process::exit(1) + }); + + + let mut command = Command::new("git"); + command + .stdin(::std::process::Stdio::inherit()) + .stdout(::std::process::Stdio::inherit()) + .stderr(::std::process::Stdio::inherit()) + .arg("-C").arg(&execpath); + + let args = rt + .cli() + .values_of("") + .map(|vs| vs.map(String::from).collect()) + .unwrap_or_else(|| vec![]); + + debug!("Adding args = {:?}", args); + command.args(&args); + + match rt.cli().subcommand() { + (external, Some(ext_m)) => { + command.arg(external); + let args = ext_m + .values_of("") + .map(|vs| vs.map(String::from).collect()) + .unwrap_or_else(|| vec![]); + + debug!("Adding subcommand '{}' and args = {:?}", external, args); + command.args(&args); + }, + _ => {}, + } + + let mut out = rt.stdout(); + + debug!("Calling: {:?}", command); + + match command.spawn().and_then(|mut c| c.wait()) { + Ok(exit_status) => { + if !exit_status.success() { + debug!("git exited with non-zero exit code: {:?}", exit_status); + eprintln!("git exited with non-zero exit code"); + ::std::process::exit(exit_status.code().unwrap_or(1)); + } + debug!("Successful exit!"); + }, + + Err(e) => { + debug!("Error calling git"); + match e.kind() { + ErrorKind::NotFound => { + let _ = writeln!(out, "Cannot find 'git' executable") + .to_exit_code() + .unwrap_or_exit(); + ::std::process::exit(1); + }, + ErrorKind::PermissionDenied => { + let _ = writeln!(out, "No permission to execute: 'git'") + .to_exit_code() + .unwrap_or_exit(); + ::std::process::exit(1); + }, + _ => { + let _ = writeln!(out, "Error spawning: {:?}", e) + .to_exit_code() + .unwrap_or_exit(); + ::std::process::exit(1); + } + } + } + } +} + diff --git a/bin/core/imag-git/src/ui.rs b/bin/core/imag-git/src/ui.rs new file mode 100644 index 00000000..31a6960c --- /dev/null +++ b/bin/core/imag-git/src/ui.rs @@ -0,0 +1,26 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015-2018 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 +// + +use clap::App; + +pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { + app +} + + diff --git a/imagrc.toml b/imagrc.toml index 7aebc22d..17f3fd7c 100644 --- a/imagrc.toml +++ b/imagrc.toml @@ -338,3 +338,10 @@ Address : {{ADR}} logs = ["default"] default = "default" +[git] +# Configuration for imag-git +# +# if this variable is _false_, imag-git will run git in $IMAG_RTP. +# if this variable is _true_, imag-git will run git in $IMAG_RTP/store +execute_in_store = false + |