diff --git a/Cargo.lock b/Cargo.lock index 951d22b..1ecb5e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "ansi_term" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ "winapi", ] @@ -33,21 +33,21 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "cc" -version = "1.0.69" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" dependencies = [ "jobserver", ] @@ -73,9 +73,9 @@ dependencies = [ [[package]] name = "clap" -version = "2.33.3" +version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "ansi_term", "atty", @@ -97,9 +97,9 @@ dependencies = [ [[package]] name = "dirs-sys" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" dependencies = [ "libc", "redox_users", @@ -124,9 +124,9 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77" dependencies = [ "cfg-if", "libc", @@ -135,13 +135,14 @@ dependencies = [ [[package]] name = "git-global" -version = "0.5.0" +version = "0.5.1" dependencies = [ "chrono", "clap", "directories", "git2", "json", + "man", "regex", "tempdir", "walkdir", @@ -149,9 +150,9 @@ dependencies = [ [[package]] name = "git2" -version = "0.13.20" +version = "0.13.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9831e983241f8c5591ed53f17d874833e2fa82cac2625f3888c50cbfe136cba" +checksum = "f29229cc1b24c0e6062f6e742aa3e256492a5323365e5ed3413599f8a5eff7d6" dependencies = [ "bitflags", "libc", @@ -182,9 +183,9 @@ dependencies = [ [[package]] name = "jobserver" -version = "0.1.22" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "972f5ae5d1cb9c6ae417789196c803205313edde988685da5e3aae0827b9e7fd" +checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" dependencies = [ "libc", ] @@ -197,15 +198,15 @@ checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" [[package]] name = "libc" -version = "0.2.98" +version = "0.2.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" +checksum = "ad5c14e80759d0939d013e6ca49930e59fc53dd8e5009132f76240c179380c09" [[package]] name = "libgit2-sys" -version = "0.12.21+1.1.0" +version = "0.12.26+1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86271bacd72b2b9e854c3dcfb82efd538f15f870e4c11af66900effb462f6825" +checksum = "19e1c899248e606fbfe68dcb31d8b0176ebab833b103824af31bddf4b7457494" dependencies = [ "cc", "libc", @@ -215,9 +216,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de5435b8549c16d423ed0c03dbaafe57cf6c3344744f1242520d59c9d8ecec66" +checksum = "6f35facd4a5673cb5a48822be2be1d4236c1c99cb4113cab7061ac720d5bf859" dependencies = [ "cc", "libc", @@ -234,17 +235,26 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "man" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebf5fa795187a80147b1ac10aaedcf5ffd3bbeb1838bda61801a1c9ad700a1c9" +dependencies = [ + "roff", +] + [[package]] name = "matches" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "memchr" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "num-integer" @@ -273,9 +283,27 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pkg-config" -version = "0.3.19" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" + +[[package]] +name = "proc-macro2" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +dependencies = [ + "proc-macro2", +] [[package]] name = "rand" @@ -316,28 +344,29 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" +checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c" dependencies = [ "bitflags", ] [[package]] name = "redox_users" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +checksum = "7776223e2696f1aa4c6b0170e83212f47296a00424305117d013dfe86fb0fe55" dependencies = [ "getrandom", "redox_syscall", + "thiserror", ] [[package]] name = "regex" -version = "1.5.4" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" dependencies = [ "aho-corasick", "memchr", @@ -359,6 +388,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "roff" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33e4fb37ba46888052c763e4ec2acfedd8f00f62897b630cadb6298b833675e" + [[package]] name = "same-file" version = "1.0.6" @@ -374,6 +409,17 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +[[package]] +name = "syn" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea297be220d52398dcc07ce15a209fce436d361735ac1db700cab3b6cdfb9f54" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + [[package]] name = "tempdir" version = "0.3.7" @@ -393,6 +439,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "time" version = "0.1.43" @@ -405,9 +471,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.2.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" dependencies = [ "tinyvec_macros", ] @@ -420,12 +486,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "unicode-bidi" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0" -dependencies = [ - "matches", -] +checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" [[package]] name = "unicode-normalization" @@ -438,9 +501,15 @@ dependencies = [ [[package]] name = "unicode-width" -version = "0.1.8" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + +[[package]] +name = "unicode-xid" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "url" diff --git a/Cargo.toml b/Cargo.toml index 3c78b9f..83d5f48 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "git-global" -version = "0.5.0" +version = "0.5.1" authors = ["Eric Petersen "] description = "Keep track of all the git repositories on your machine." @@ -17,9 +17,21 @@ categories = ["command-line-utilities", "development-tools"] edition = "2018" +default-run = "git-global" + [[bin]] name = "git-global" +path = "src/main.rs" +doc = false + +[[bin]] +name = "generate-manpage" +path = "src/generate_manpage.rs" doc = false +required-features = ["manpage"] + +[features] +manpage = ["man"] [dependencies] chrono = "0.4" @@ -35,3 +47,7 @@ tempdir = "0.3" [dependencies.git2] version = "0.13" default-features = false # don't want SSH/HTTPS/Curl + +[dependencies.man] +version = "0.3" +optional = true diff --git a/README.md b/README.md index 94e7d15..8c3939d 100644 --- a/README.md +++ b/README.md @@ -7,14 +7,19 @@ Use `git-global` to keep track of all the git repositories on your machine. This is a Rust program that you can install with `cargo install git-global`. -(To obtain `cargo` and Rust, see https://rustup.rs.) Once installed, you gain -an extra git subcommand that you can run from anywhere to check up on all your -git repos: `git global`. +(To obtain `cargo` and Rust, see https://rustup.rs.) Once installed, you can +optionally install the manpage with `git global install-manpage` -Use `git global ` to: +Once installed, you gain an extra git subcommand that you can run from anywhere +to check up on all your git repos: `git global`. Use `git global ` +to: +* `git global ahead`: show repos where branches contain commits that are not + present on any of the remotes * `git global info`: show meta-information about git-global itself (configuration, number of known repos, etc.) +* `git global install-manpage`: (non-functional) attempt to install + git-global's manpage * `git global list`: show list of all known repos * `git global scan`: update the cache of known repos by searching your filesystem @@ -23,8 +28,6 @@ Use `git global ` to: * `git global status`: show `git status -s` for all your repos with any changes * `git global unstaged`: show status of the working directory for repos with such changes -* `git global ahead`: show repos where branches contain commits that are not - present on any of the remotes ## Command-line flags @@ -71,6 +74,16 @@ The full list of configuration options supported in the `global` section of * `show-untracked`: Whether to include untracked files in output (default: `true`) +## Manpage generation + +An up-to-date copy of the manpage lives in the repository at +[doc/git-global.1](doc/git-global.1). To generate it from a local clone of the +repo, run: + +``` +$ cargo run --bin generate-manpage --features=manpage > doc/git-global.1 +``` + ## Ideas The following are some ideas I've had about future subcommands and features: @@ -95,6 +108,9 @@ The following are some ideas I've had about future subcommands and features: ## Release Notes +* 0.5.1 (2022-03-17) + * Add the `generate-manpage` binary and (non-functional) `install-manpage` + subcommand. * 0.5.0 (2021-07-12) * Add the `ahead` subcommand - thanks, koalp!. * 0.4.1 (2021-06-03) diff --git a/doc/git-global.1 b/doc/git-global.1 new file mode 100644 index 0000000..9b93e19 --- /dev/null +++ b/doc/git-global.1 @@ -0,0 +1,61 @@ +.TH GIT-GLOBAL 1 +.SH NAME +git\-global \- Keep track of all the git repositories on your machine. +.SH SYNOPSIS +\fBgit\-global\fR [FLAGS] +.SH FLAGS +.TP +\fBj\fR, \fBjson\fR +Output subcommand results in JSON. + +.TP +\fBu\fR, \fBuntracked\fR +Show untracked files in output. + +.TP +\fBt\fR, \fBnountracked\fR +Don't show untracked files in output. +.SH VERSION +Crate version 0.5.1 + + +.SH SUBCOMMANDS +The following subcommands are supported by git global; use git's global config to set your default choice. + +ahead: Shows repos with changes that are not pushed to a remote + +info: Shows meta\-information about git\-global + +install\-manpage: Attempts to install git\-global's man page + +list: Lists all known repos + +scan: Updates cache of known repos + +staged: Shows git index status for repos with staged changes + +stashed: Shows repos with stashed changes + +status: Shows status (`git status \-s`) for repos with any changes + +unstaged: Shows working dir status for repos with unstaged changes + + +.SH EXIT STATUS +.TP +\fB0\fR +Successful program execution. + +.TP +\fB1\fR +Unsuccessful program execution. + +.TP +\fB101\fR +The program panicked. +.SH AUTHOR +.P +.RS 2 +.nf +Eric Petersen + diff --git a/src/cli.rs b/src/cli.rs index e4c26dd..1621294 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -2,33 +2,39 @@ use std::io::{stderr, stdout, Write}; -use clap::{crate_version, App, Arg, ArgMatches, SubCommand}; +use clap::{ + app_from_crate, crate_authors, crate_description, crate_name, + crate_version, App, Arg, ArgMatches, SubCommand, +}; use json::object; use crate::config::Config; use crate::subcommands; /// Returns the definitive clap::App instance for git-global. -fn get_clap_app<'a, 'b>() -> App<'a, 'b> { - App::new("git-global") - .version(crate_version!()) - .author("Eric Petersen ") - .about("git subcommand for working with all git repos on a machine") +pub fn get_clap_app<'a, 'b>() -> App<'a, 'b> { + app_from_crate!() .arg( Arg::with_name("json") + .short("j") .long("json") + .global(true) .help("Output subcommand results in JSON."), ) .arg( Arg::with_name("untracked") + .short("u") .long("untracked") .conflicts_with("nountracked") + .global(true) .help("Show untracked files in output."), ) .arg( Arg::with_name("nountracked") + .short("t") .long("nountracked") .conflicts_with("untracked") + .global(true) .help("Don't show untracked files in output."), ) .subcommands(subcommands::get_subcommands().iter().map( diff --git a/src/config.rs b/src/config.rs index b7afa28..dae89c4 100644 --- a/src/config.rs +++ b/src/config.rs @@ -4,6 +4,7 @@ //! repos on the machine, path patterns to ignore when scanning for repos, the //! location of a cache file, and other config options for running git-global. +use std::env; use std::fs::{create_dir_all, remove_file, File}; use std::io::{BufRead, BufReader, Write}; use std::path::{Path, PathBuf}; @@ -68,6 +69,12 @@ pub struct Config { /// Default: `repos.txt` in the user's XDG cache directory, if we understand /// XDG for the host system. pub cache_file: Option, + + /// Optional path to our manpage, regardless of whether it's installed. + /// + /// Default: `git-global.1` in the relevant manpages directory, if we + /// understand where that should be for the host system. + pub manpage_file: Option, } impl Default for Config { @@ -89,6 +96,17 @@ impl Config { let cache_file = ProjectDirs::from(QUALIFIER, ORGANIZATION, APPLICATION) .map(|project_dirs| project_dirs.cache_dir().join(CACHE_FILE)); + let manpage_file = match env::consts::OS { + // Consider ~/.local/share/man/man1/, too. + "linux" => Some(PathBuf::from("/usr/share/man/man1/git-global.1")), + "macos" => Some(PathBuf::from("/usr/share/man/man1/git-global.1")), + "windows" => env::var("MSYSTEM").ok().and_then(|val| { + (val == "MINGW64").then(|| { + PathBuf::from("/mingw64/share/doc/git-doc/git-global.html") + }) + }), + _ => None, + }; match ::git2::Config::open_default() { Ok(cfg) => Config { basedir: cfg.get_path(SETTING_BASEDIR).unwrap_or(homedir), @@ -111,6 +129,7 @@ impl Config { .get_bool(SETTING_SHOW_UNTRACKED) .unwrap_or(DEFAULT_SHOW_UNTRACKED), cache_file, + manpage_file, }, Err(_) => { // Build the default configuration. @@ -122,6 +141,7 @@ impl Config { default_cmd: String::from(DEFAULT_CMD), show_untracked: DEFAULT_SHOW_UNTRACKED, cache_file, + manpage_file, } } } diff --git a/src/generate_manpage.rs b/src/generate_manpage.rs new file mode 100644 index 0000000..4beb514 --- /dev/null +++ b/src/generate_manpage.rs @@ -0,0 +1,38 @@ +use man::prelude::*; + +fn main() { + // TODO(peap): Consider switching to clap_mangen. + let app = git_global::get_clap_app(); + let name_and_email: Vec<&str> = + app.p.meta.author.unwrap().split(" <").collect(); + let name = name_and_email[0]; + let email = name_and_email[1].strip_suffix(">").unwrap(); + let mut page = Manual::new(app.get_name()) + .about(app.p.meta.about.unwrap()) + .author(Author::new(name).email(email)) + .custom(Section::new("version").paragraph(&format!( + "Crate version {}", + app.p.meta.version.unwrap() + ))); + for arg in app.p.global_args { + page = page.flag( + Flag::new() + .short(&arg.s.short.unwrap().to_string()) + .long(arg.s.long.unwrap()) + .help(arg.b.help.unwrap()), + ); + } + let mut commands_section = Section::new("subcommands").paragraph( + "The following subcommands are supported by git global; \ + use git's global config to set your default choice.", + ); + for cmd in app.p.subcommands { + commands_section = commands_section.paragraph(&format!( + "{}: {}", + cmd.p.meta.name, + cmd.p.meta.about.unwrap() + )); + } + page = page.custom(commands_section); + println!("{}", page.render()); +} diff --git a/src/lib.rs b/src/lib.rs index ed4b05e..b5a74d9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,8 @@ //! $ git global info # show information about git-global itself //! $ git global list # show all git repos git-global knows about //! $ git global scan # search your filesystem for git repos and update cache +//! # ... +//! $ git global help # show usage and all subcommands //! ``` //! //! # Public Interface @@ -54,7 +56,7 @@ mod repo; mod report; pub mod subcommands; // Using `pub mod` so we see the docs. -pub use cli::run_from_command_line; +pub use cli::{get_clap_app, run_from_command_line}; pub use config::Config; pub use errors::{GitGlobalError, Result}; pub use repo::Repo; diff --git a/src/subcommands.rs b/src/subcommands.rs index 7c13c55..64c1cc3 100644 --- a/src/subcommands.rs +++ b/src/subcommands.rs @@ -1,6 +1,7 @@ //! Subcommand implementations and dispatch function `run()`. pub mod ahead; pub mod info; +pub mod install_manpage; pub mod list; pub mod scan; pub mod staged; @@ -27,6 +28,7 @@ pub fn run(maybe_subcmd: Option<&str>, config: Config) -> Result { "status" => status::execute(config), "unstaged" => unstaged::execute(config), "ahead" => ahead::execute(config), + "install-manpage" => install_manpage::execute(config), cmd => Err(GitGlobalError::BadSubcommand(cmd.to_string())), } } @@ -36,7 +38,15 @@ pub fn run(maybe_subcmd: Option<&str>, config: Config) -> Result { /// Used for building the clap::App in the cli module. pub fn get_subcommands() -> Vec<(&'static str, &'static str)> { vec![ + ( + "ahead", + "Shows repos with changes that are not pushed to a remote", + ), ("info", "Shows meta-information about git-global"), + ( + "install-manpage", + "Attempts to install git-global's man page", + ), ("list", "Lists all known repos"), ("scan", "Updates cache of known repos"), ( @@ -52,9 +62,5 @@ pub fn get_subcommands() -> Vec<(&'static str, &'static str)> { "unstaged", "Shows working dir status for repos with unstaged changes", ), - ( - "ahead", - "Shows repos with changes that are not pushed to a remote", - ), ] } diff --git a/src/subcommands/info.rs b/src/subcommands/info.rs index 4893539..cd015fc 100644 --- a/src/subcommands/info.rs +++ b/src/subcommands/info.rs @@ -3,6 +3,7 @@ use chrono::Duration; use clap::crate_version; +use std::env; use std::path::PathBuf; use std::time::SystemTime; @@ -44,6 +45,12 @@ pub fn execute(mut config: Config) -> Result { report.add_message(underline); report.add_message(format!("Number of repos: {}", repos.len())); report.add_message(format!("Base directory: {}", config.basedir.display())); + report.add_message("Ignored patterns:".to_string()); + for pat in config.ignored_patterns.iter() { + report.add_message(format!(" {}", pat)); + } + report.add_message(format!("Default command: {}", config.default_cmd)); + report.add_message(format!("Show untracked: {}", config.show_untracked)); if let Some(cache_file) = config.cache_file { report.add_message(format!("Cache file: {}", cache_file.display())); if let Some(age) = get_age(cache_file) { @@ -52,11 +59,11 @@ pub fn execute(mut config: Config) -> Result { } else { report.add_message("Cache file: ".to_string()); } - report.add_message("Ignored patterns:".to_string()); - for pat in config.ignored_patterns.iter() { - report.add_message(format!(" {}", pat)); + if let Some(manpage_file) = config.manpage_file { + report.add_message(format!("Manpage file: {}", manpage_file.display())); + } else { + report.add_message("Manpage file: ".to_string()); } - report.add_message(format!("Default command: {}", config.default_cmd)); - report.add_message(format!("Show untracked: {}", config.show_untracked)); + report.add_message(format!("Detected OS: {}", env::consts::OS)); Ok(report) } diff --git a/src/subcommands/install_manpage.rs b/src/subcommands/install_manpage.rs new file mode 100644 index 0000000..edb1442 --- /dev/null +++ b/src/subcommands/install_manpage.rs @@ -0,0 +1,29 @@ +//! The `install-manpage` subcommand: attempts to install a man page. + +use crate::config::Config; +use crate::errors::Result; +use crate::report::Report; + +// TODO(peap): Add option to just generate the file for the user to stick somewhere? + +/// Attempts to install git-global's man page to the relevant directory. +/// This is a work-around to not maintaining distribution-specific packages +/// and Cargo not providing this functionality for crates. +pub fn execute(mut config: Config) -> Result { + let repos = config.get_repos(); + let mut report = Report::new(&repos); + report.add_message("This feature is a work-in-progress.".to_string()); + report.add_message( + "In the meantime, you can find the manpage at \ + https://raw.githubusercontent.com/peap/git-global/master/doc/git-global.1".to_string() + ); + if let Some(manpage_file) = config.manpage_file { + report.add_message(format!( + "...would write file to {}", + manpage_file.display() + )); + } else { + report.add_message("...not sure where to put it!".to_string()); + } + Ok(report) +} diff --git a/tests/subcommands.rs b/tests/subcommands.rs index f84b897..c4b7269 100644 --- a/tests/subcommands.rs +++ b/tests/subcommands.rs @@ -1,5 +1,6 @@ mod utils; +use std::env; use std::io::Cursor; use std::path::PathBuf; @@ -16,7 +17,7 @@ fn report_to_string(report: &Report) -> String { #[test] fn test_info() { - utils::with_base_dir_of_three_repos(|config| { + utils::with_base_dir_of_three_repos(|mut config| { let basedir = config.basedir.clone(); let cache = config .cache_file @@ -25,17 +26,29 @@ fn test_info() { .to_str() .unwrap() .to_string(); + if config.manpage_file.is_none() { + config.manpage_file = Some(PathBuf::from("/test")); + } + let manpage = config + .manpage_file + .clone() + .unwrap() + .to_str() + .unwrap() + .to_string(); let report = subcommands::info::execute(config).unwrap(); let expected = vec![ format!(r"^git-global {}$", crate_version!()), format!(r"^============+"), format!(r"^Number of repos: 3$"), format!(r"^Base directory: {}$", escape(basedir.to_str().unwrap())), - format!(r"^Cache file: {}$", escape(&cache)), - format!(r"^Cache file age: 0d, 0h, 0m, .s$"), format!(r"^Ignored patterns:$"), format!(r"^Default command: status$"), format!(r"^Show untracked: true$"), + format!(r"^Cache file: {}$", escape(&cache)), + format!(r"^Cache file age: 0d, 0h, 0m, .s$"), + format!(r"^Manpage file: {}$", escape(&manpage)), + format!(r"^Detected OS: {}$", escape(env::consts::OS)), format!(r"^$"), ]; let output = report_to_string(&report); diff --git a/tests/utils.rs b/tests/utils.rs index 2410614..8568c47 100644 --- a/tests/utils.rs +++ b/tests/utils.rs @@ -41,6 +41,7 @@ where cache_file: Some( base_path.clone().join("test-cache-file.txt").to_path_buf(), ), + manpage_file: None, }; test(config); }