From e6cfc9c482c9f1a1c6dfba10aadf1c5c6a32f0d3 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 26 Nov 2015 09:35:23 +0200 Subject: Add --pager, --pager-option common options --- bpkg/common-options.cli | 63 ++++++++++++++++++++++++++++++++----------------- bpkg/help.cxx | 63 ++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 91 insertions(+), 35 deletions(-) diff --git a/bpkg/common-options.cli b/bpkg/common-options.cli index f07d70e..06a12b1 100644 --- a/bpkg/common-options.cli +++ b/bpkg/common-options.cli @@ -52,9 +52,10 @@ namespace bpkg uint16_t --verbose = 1 { "", - "Set the diagnostics verbosity to between 0 (disabled) and - 6 (lots of information). The default is 1. The following additional - classes of diagnostics are produced at each level: + "Set the diagnostics verbosity to between 0 and 6. Level 0 + disables any non-error messages while level 6 produces lots of + information, with level 1 beeing the default. The following additional + types of diagnostics are produced at each level: \ol| @@ -74,12 +75,12 @@ namespace bpkg path --fetch { "", - "The fetch program that should be used to download remote resources. - Currently, \cb{bpkg} recognizes \cb{curl}, \cb{wget}, and \cb{fetch}. - Note that the last component of must contain one of these - names as a substring in order for \cb{bpkg} to recognize which - program is being used. You can also specify additional options that - should be passed to the fetch program with \cb{--fetch-option}. + "The fetch program to be used to download remote resources. Currently, + \cb{bpkg} recognizes \cb{curl}, \cb{wget}, and \cb{fetch}. Note that + the last component of must contain one of these names as a + substring in order for \cb{bpkg} to recognize which program is being + used. You can also specify additional options that should be passed + to the fetch program with \cb{--fetch-option}. If the fetch program is not specified, then \cb{bpkg} will try to discover if one of the above program is available and use that. @@ -91,27 +92,47 @@ namespace bpkg strings --fetch-option { "", - "Additional option that should be passed to the fetch program. See - \cb{--fetch} for more information on the fetch program. Repeat this - option to specify multiple fetch options." + "Additional option to be passed to the fetch program. See \cb{--fetch} + for more information on the fetch program. Repeat this option to + specify multiple fetch options." }; path --tar = "tar" { "", - "The tar program that should be used to extract package archives. For - example, \cb{gtar} or \cb{bsdtar}. You can also specify additional - options that should be passed to the tar program with - \cb{--tar-option}. If the tar program is not explicitly specified, - then \cb{bpkg} will use \cb{tar} by default." + "The tar program to be used to extract package archives. For example, + \cb{gtar} or \cb{bsdtar}. You can also specify additional options that + should be passed to the tar program with \cb{--tar-option}. If the tar + program is not explicitly specified, then \cb{bpkg} will use \cb{tar} + by default." }; strings --tar-option { "", - "Additional option that should be passed to the tar program. See - \cb{--tar} for more information on the tar program. Repeat this - option to specify multiple tar options." + "Additional option to be passed to the tar program. See \cb{--tar} for + more information on the tar program. Repeat this option to specify + multiple tar options." + }; + + string --pager // String to allow empty value. + { + "", + "The pager program to be used to show text, such as help. Commonly + used pager programs are \cb{less} and \cb{more}. You can also specify + additional options that should be passed to the pager program with + \cb{--pager-option}. If an empty string is specified as the pager + program, then no pager will be used. If the pager program is not + explicitly specified, then \cb{bpkg} will try to use \cb{less}. If it + is not available, then no pager will be used." + }; + + strings --pager-option + { + "", + "Additional option to be passed to the pager program. See \cb{--pager} + for more information on the pager program. Repeat this option to + specify multiple pager options." }; // The following option is "fake" in that it is actually handled by @@ -120,7 +141,7 @@ namespace bpkg string --options-file { "", - "Read additional options from with each option appearing on a + "Read additional options from . Each option should appearing on a separate line optionally followed by space and an option value. Empty lines and lines starting with \cb{#} are ignored. Option values can be enclosed in double (\cb{\"}) or single (\cb{'}) quotes to preserve diff --git a/bpkg/help.cxx b/bpkg/help.cxx index 31a7cdd..6c16088 100644 --- a/bpkg/help.cxx +++ b/bpkg/help.cxx @@ -30,22 +30,47 @@ namespace bpkg { struct pager { - pager (const string& name) + pager (const common_options& co, const string& name) { - // First try less. - // - try + cstrings args; + string prompt; + + bool up (co.pager_specified ()); // User's pager. + + if (up) + { + if (co.pager ().empty ()) + return; // No pager should be used. + + args.push_back (co.pager ().c_str ()); + } + else { - string prompt ("-Ps" + name + " (press q to quit, h for help)"); + // By default try less. + // + prompt = "-Ps" + name + " (press q to quit, h for help)"; + + args.push_back ("less"); + args.push_back ("-R"); // Handle ANSI color. + args.push_back (prompt.c_str ()); + } + + // Add extra pager options. + // + for (const string& o: co.pager_option ()) + args.push_back (o.c_str ()); - const char* args[] = { - "less", - "-R", // ANSI color - prompt.c_str (), - nullptr - }; + args.push_back (nullptr); - p_ = process (args, -1); // Redirect child's stdin to a pipe. + if (verb >= 2) + print_process (args); + + // Ignore errors and go without a pager unless the pager was specified + // by the user. + // + try + { + p_ = process (args.data (), -1); // Redirect child's stdin to a pipe. // Wait a bit and see if the pager has exited before reading // anything (e.g., because exec() couldn't find the program). @@ -63,14 +88,24 @@ namespace bpkg #else _close (p_.out_fd); #endif + if (up) + fail << "pager " << args[0] << " exited unexpectedly"; } else os_.open (p_.out_fd); } catch (const process_error& e) { + // Ignore unless it was a user-specified pager. + // + if (up) + error << "unable to execute " << args[0] << ": " << e.what (); + if (e.child ()) exit (1); + + if (up) + throw failed (); } } @@ -95,7 +130,7 @@ namespace bpkg }; int - help (const help_options&, const string& t, usage_function* usage) + help (const help_options& o, const string& t, usage_function* usage) { if (usage == nullptr) // Not a command. { @@ -108,7 +143,7 @@ namespace bpkg info << "run 'bpkg help' for more information"; } - pager p ("bpkg " + (t.empty () ? "help" : t)); + pager p (o, "bpkg " + (t.empty () ? "help" : t)); usage (p.stream (), cli::usage_para::none); // If the pager failed, assume it has issued some diagnostics. -- cgit v1.1