aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bpkg/utility.cxx43
-rw-r--r--bpkg/utility.hxx10
-rw-r--r--tests/rep-auth.test8
3 files changed, 18 insertions, 43 deletions
diff --git a/bpkg/utility.cxx b/bpkg/utility.cxx
index 8a456d0..c6f2fae 100644
--- a/bpkg/utility.cxx
+++ b/bpkg/utility.cxx
@@ -6,6 +6,7 @@
#include <iostream> // cout, cin
+#include <libbutl/prompt.mxx>
#include <libbutl/process.mxx>
#include <libbutl/fdstream.mxx>
@@ -85,42 +86,16 @@ namespace bpkg
bool stderr_term;
bool
- yn_prompt (const char* prompt, char def)
+ yn_prompt (const string& p, char d)
{
- // Writing a robust Y/N prompt is more difficult than one would
- // expect...
- //
- string a;
- do
+ try
{
- *diag_stream << prompt << ' ';
-
- // getline() will set the failbit if it failed to extract anything,
- // not even the delimiter and eofbit if it reached eof before seeing
- // the delimiter.
- //
- getline (cin, a);
-
- bool f (cin.fail ());
- bool e (cin.eof ());
-
- if (f || e)
- *diag_stream << endl; // Assume no delimiter (newline).
-
- if (f)
- fail << "unable to read y/n answer from STDOUT";
-
- if (a.empty () && def != '\0')
- {
- // Don't treat eof as the default answer. We need to see the
- // actual newline.
- //
- if (!e)
- a = def;
- }
- } while (a != "y" && a != "n");
-
- return a == "y";
+ return butl::yn_prompt (p, d);
+ }
+ catch (io_error&)
+ {
+ fail << "unable to read y/n answer from stdin";
+ }
}
bool
diff --git a/bpkg/utility.hxx b/bpkg/utility.hxx
index 19d664e..c0c361f 100644
--- a/bpkg/utility.hxx
+++ b/bpkg/utility.hxx
@@ -88,13 +88,13 @@ namespace bpkg
//
extern bool stderr_term; // True if stderr is a terminal.
- // Y/N prompt. The def argument, if specified, should be either 'y'
- // or 'n'. It is used as the default answer, in case the user just
- // hits enter. Issue diagnostics and throw failed if no answer could
- // be extracted from STDOUT (e.g., because it was closed).
+ // Y/N prompt. See butl::yn_prompt() for details (this is a thin wrapper).
+ //
+ // Issue diagnostics and throw failed if no answer could be extracted from
+ // stdin (e.g., because it was closed).
//
bool
- yn_prompt (const char* prompt, char def = '\0');
+ yn_prompt (const string& prompt, char def = '\0');
// Filesystem.
//
diff --git a/tests/rep-auth.test b/tests/rep-auth.test
index e27aae2..640f828 100644
--- a/tests/rep-auth.test
+++ b/tests/rep-auth.test
@@ -183,7 +183,7 @@ sc = " " # Space character to append to here-document line when required.
certificate SHA256 fingerprint:
$cert_fp
trust this certificate? [y/n]$sc
- error: unable to read y/n answer from STDOUT
+ error: unable to read y/n answer from stdin
EOE
$not_fetched
@@ -293,7 +293,7 @@ sc = " " # Space character to append to here-document line when required.
certificate SHA256 fingerprint:
$cert_fp
trust this certificate? [y/n]$sc
- error: unable to read y/n answer from STDOUT
+ error: unable to read y/n answer from stdin
EOE
: trust-fp
@@ -457,7 +457,7 @@ sc = " " # Space character to append to here-document line when required.
fetching pkg:build2.org/rep-auth/unsigned1
warning: repository pkg:build2.org/rep-auth/unsigned1 is unsigned
%continue without authenticating repositories at .+\? \[y/n\] %
- error: unable to read y/n answer from STDOUT
+ error: unable to read y/n answer from stdin
EOE
$not_fetched
@@ -535,7 +535,7 @@ sc = " " # Space character to append to here-document line when required.
$rep_info 2>>~%EOE% != 0
warning: repository pkg:build2.org/rep-auth/unsigned1 is unsigned
%continue without authenticating repositories at .+\? \[y/n\] %
- error: unable to read y/n answer from STDOUT
+ error: unable to read y/n answer from stdin
EOE
: trust-yes