tokuhirom / Minilla

Authorizing tool for CPAN modules
https://metacpan.org/release/Minilla
Other
98 stars 65 forks source link

infinite loop: Release to CPAN ? [y/n] - UploadToCPAN.pm lines 45-54 #331

Closed rshingleton closed 8 months ago

rshingleton commented 8 months ago

Just tried to do a release after being upgrade to a new Mac M2. All versions of Minilla and dependencies should be the most recent. Doing minil release continues as expected until the prompt sections and then begins to loop:

minil release Retrieving meta data from... ...

Release to CPAN ? [y/n]
Release to CPAN ? [y/n]
Release to CPAN ? [y/n]
Release to CPAN ? [y/n]
Release to CPAN ? [y/n]
Release to CPAN ? [y/n]
Release to CPAN ? [y/n]
Release to CPAN ? [y^CRelease to CPAN ? [y/n]

Unable to perform any functions at this point aside from ^C.

Looking through the code, I think there something going on in UploadToCPAN.pm

        PROMPT: while (1) {
            my $answer = prompt("Release to " . ($config->{upload_uri} || 'CPAN') . ' ? [y/n] ');
            if ($answer =~ /y/i) {
                last PROMPT;
            } elsif ($answer =~ /n/i) {
                errorf("Giving up!\n");
            } else {
                redo PROMPT;
            }
        }

Could be something has changed in ExtUtils::MakeMaker qw(prompt)?

Could be something with the Mac M* models on arm64 chips? I will test on a Linux box to see if I can get it to work there to eliminate this possibility.

OS: Darwin 23.2.0 Darwin Kernel Version 23.2.0: Wed Nov 15 21:55:06 PST 2023; root:xnu-10002.61.3~2/RELEASE_ARM64_T6020 arm64

rshingleton commented 8 months ago

I believe it may have something to do with the prompt functionality on the Mac M2 or my install as the prompt functionality seems to work on a Linux box.

I noticed when running the Linux test that it skips right past the Next Release? [0.01] prompt on the Mac as well, so this issue is not limited to UploadToCPAN.pm, rather I think it's a problem with how the prompt call is being handled in ExtUtils::MakeMaker.

I've tried reinstalling on the Mac with the same outcome.

Mac Perl: This is perl 5, version 36, subversion 3 (v5.36.3) built for darwin-thread-multi-2level Darwin Kernel Version 23.2.0: Wed Nov 15 21:55:06 PST 2023; root:xnu-10002.61.3~2/RELEASE_ARM64_T6020 arm64

Linux Perl: This is perl 5, version 36, subversion 3 (v5.36.3) built for x86_64-linux-thread-multi 5.14.0-362.8.1.el9_3.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Oct 3 11:12:36 EDT 2023 x86_64 x86_64 x86_64 GNU/Linux

Both installations done within a few weeks of each other, so there should little to no variations in the underlying modules.

skaji commented 8 months ago

Does the following script work on your environment?

#!/usr/bin/env perl
use strict;
use warnings;

use ExtUtils::MakeMaker qw(prompt);

warn sprintf "ExtUtils::MakeMaker %s in %s\n",
    ExtUtils::MakeMaker->VERSION, $INC{ "ExtUtils/MakeMaker.pm" };

PROMPT: while (1) {
    my $answer = prompt("Release to CPAN? [y/n]");
    if ($answer =~ /y/i) {
        last PROMPT;
    } elsif ($answer =~ /n/i) {
        die "Giving up!\n";
    } else {
        redo PROMPT
    }
}

warn "exit\n";
rshingleton commented 8 months ago

I will check it this afternoon/evening and do some additional testing.

rshingleton commented 8 months ago

Ok, I found the issue. Somewhere along the way of getting things installed on this new M2 Mac, the PERL_MM_USE_DEFAULT got set in my .bashrc file.

export PERL_MM_USE_DEFAULT=1

The only reason I determined this was the issue was digging into ExtUtils::MakeMaker::prompt and modifying my local code to do carp outputs.

sub prompt ($;$) {  ## no critic
    my($mess, $def) = @_;
    confess("prompt function called without an argument")
        unless defined $mess;

    my $isa_tty = -t STDIN && (-t STDOUT || !(-f STDOUT || -c STDOUT)) ;

    my $dispdef = defined $def ? "[$def] " : " ";
    $def = defined $def ? $def : "";

    local $|=1;
    local $\;
    print "$mess $dispdef";

    my $ans;
    if ($ENV{PERL_MM_USE_DEFAULT} || (!$isa_tty && eof STDIN)) {
        print "$def\n";
    }
    else {
        $ans = <STDIN>;
        if( defined $ans ) {
            $ans =~ s{\015?\012$}{};
        }
        else { # user hit ctrl-D
            print "\n";
        }
    }

    return (!defined $ans || $ans eq '') ? $def : $ans;
}

At line 215, if ($ENV{PERL_MM_USE_DEFAULT} || (!$isa_tty && eof STDIN)) {, this check is made and sends it into the print "$def\n"; which ends up causing the infinite loop in Minilla since there's no wait for <STDIN>.

I'm not sure why I originally set the PERL_MM_USE_DEFAULT but it was around some openssl installation stuff dealing with homebrew libraries, so I probably copied it from some post trying to get something to work installing some Perl crypt or openssl support packages.

I was able to solve this by removing the export PERL_MM_USE_DEFAULT=1 and unsetting the ENV var. Since I don't know the reason I put the env var in or the reason for that conditional in ExtUtils::MakeMaker::prompt, I'm going to call this a non-issue for Minilla.