The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Changes 04
META.json 11
META.yml 11
README 39
eg/ask 33
lib/Sysadm/Install.pm 1843
6 files changed (This is a version diff) 2661
@@ -2,6 +2,10 @@
 Revision history for Sysadm::Install
 ########################################
 
+0.46  (2015/06/23)
+    (ms) ask() and pick() now support getting the user's response on the 
+         tty, instead of stdin, so they can be used from within a pipe.
+
 0.45  (2015/05/25)
     (ms) Alexandr Ciornii fixed manifest and tests for the Windows platform
 
@@ -50,5 +50,5 @@
          "url" : "http://github.com/mschilli/sysadm-install-perl"
       }
    },
-   "version" : "0.45"
+   "version" : "0.46"
 }
@@ -29,4 +29,4 @@ requires:
   Term::ReadKey: '0'
 resources:
   repository: http://github.com/mschilli/sysadm-install-perl
-version: '0.45'
+version: '0.46'
@@ -1,5 +1,5 @@
 ######################################################################
-    Sysadm::Install 0.45
+    Sysadm::Install 0.46
 ######################################################################
 
 NAME
@@ -83,7 +83,7 @@ DESCRIPTION
         Untar the tarball in $tgz_file in directory $dir. Create $dir if it
         doesn't exist yet.
 
-    "pick($prompt, $options, $default)"
+    "pick($prompt, $options, $default, $opts)"
         Ask the user to pick an item from a displayed list. $prompt is the
         text displayed, $options is a referenc to an array of choices, and
         $default is the number (starting from 1, not 0) of the default item.
@@ -105,10 +105,16 @@ DESCRIPTION
         If the user enters 1, 2 or 3, the corresponding text string
         ("apple", "pear", "pineapple" will be returned by "pick()".
 
-    "ask($prompt, $default)"
+        If the optional $opts hash has "{ tty => 1 }" set, then the user
+        reponse will be expected from the console, not STDIN.
+
+    "ask($prompt, $default, $opts)"
         Ask the user to either hit *Enter* and select the displayed default
         or to type in another string.
 
+        If the optional $opts hash has "{ tty => 1 }" set, then the user
+        reponse will be expected from the console, not STDIN.
+
     "mkd($dir)"
         Create a directory of arbitrary depth, just like
         "File::Path::mkpath".
@@ -8,9 +8,9 @@ use strict;
 
 use Sysadm::Install qw(ask pick);
 
-my $name = ask("Type in your name", "Joe");
+my $name = ask("Type in your name", "Joe", {tty => 1});
 print "Your name is $name.\n";
 
-my $fruit = pick("Pick a fruit", ["apple", "pear", "pineapple"], 3);
+my $fruit = pick("Pick a fruit", ["apple", "pear", "pineapple"], 
+                 3, {tty => 1});
 print "Your picked $fruit.\n";
-
@@ -6,7 +6,7 @@ use 5.006;
 use strict;
 use warnings;
 
-our $VERSION = '0.45';
+our $VERSION = '0.46';
 
 use File::Copy;
 use File::Path;
@@ -365,7 +365,7 @@ sub untar_in {
 
 =pod
 
-=item C<pick($prompt, $options, $default)>
+=item C<pick($prompt, $options, $default, $opts)>
 
 Ask the user to pick an item from a displayed list. C<$prompt>
 is the text displayed, C<$options> is a referenc to an array of
@@ -389,12 +389,15 @@ If the user enters C<1>, C<2> or C<3>, the corresponding text string
 (C<"apple">, C<"pear">, C<"pineapple"> will be returned by
 C<pick()>.
 
+If the optional C<$opts> hash has C<{ tty =E<gt> 1 }> set, then 
+the user reponse will be expected from the console, not STDIN.
+
 =cut
 
 ##################################################
 sub pick {
 ##################################################
-    my ($prompt, $options, $default) = @_;    
+    my ($prompt, $options, $default, $opts) = @_;    
 
     local $Log::Log4perl::caller_depth =
           $Log::Log4perl::caller_depth + 1;
@@ -402,23 +405,23 @@ sub pick {
     my $default_int;
     my %files;
 
-    if(@_ != 3 or ref($options) ne "ARRAY") {
+    if(@_ < 3 or ref($options) ne "ARRAY") {
         LOGCROAK("pick called with wrong #/type of args");
     }
     
     {
         my $count = 0;
 
+        my $user_prompt = "";
+
         foreach (@$options) {
-            print STDERR "[", ++$count, "] $_\n";
+            $user_prompt .= "[" . ++$count . "] $_\n";
             $default_int = $count if $count eq $default;
             $files{$count} = $_;
         }
     
-        print STDERR "$prompt [$default_int]> "
-            or die "Couldn't write STDERR: ($!)";
-        my $input = <STDIN>;
-        chomp($input) if defined $input;
+        $user_prompt .= "$prompt [$default_int]> ";
+        my $input = user_input($user_prompt, $opts);
 
         $input = $default_int if !defined $input or !length($input);
 
@@ -431,36 +434,58 @@ sub pick {
 
 =pod
 
-=item C<ask($prompt, $default)>
+=item C<ask($prompt, $default, $opts)>
 
 Ask the user to either hit I<Enter> and select the displayed default
 or to type in another string.
 
+If the optional C<$opts> hash has C<{ tty =E<gt> 1 }> set, then 
+the user reponse will be expected from the console, not STDIN.
+
 =cut
 
 ##################################################
 sub ask {
 ##################################################
-    my ($prompt, $default) = @_;    
+    my ($prompt, $default, $opts) = @_;    
+
+    $opts = {} if !defined $opts;
 
     local $Log::Log4perl::caller_depth =
           $Log::Log4perl::caller_depth + 1;
 
-    if(@_ != 2) {
+    if(@_ < 2) {
         LOGCROAK("ask() called with wrong # of args");
     }
 
-    print STDERR "$prompt [$default]> "
-        or die "Couldn't write STDERR: ($!)";
-
-    my $value = <STDIN>;
-    chomp $value;
-
+    my $value = user_input("$prompt [$default]> ", $opts);
     $value = $default if $value eq "";
 
     return $value;
 }
 
+##################################################
+sub user_input {
+##################################################
+    my ($prompt, $opts) = @_;    
+
+    $opts = {} if !defined $opts;
+
+    my $fh = *STDIN;
+    if( $opts->{ tty } ) {
+        open $fh, "<", '/dev/tty' or 
+            die "Cannot open /dev/tty ($!)";
+    }
+
+    print STDERR $prompt
+        or die "Couldn't write STDERR: ($!)";
+
+    my $input = <$fh>;
+    chomp $input if defined $input;
+
+    return $input;
+}
+
 =pod
 
 =item C<mkd($dir)>