Skip to content

Commit 260eb49

Browse files
committed
Merge pull request #1522 from uralm1/load_rexfile_test_and_fix
Fix #1521 lib/Rex/CLI.pm: Use $SIG{__WARN__} when loading Rexfile instead of stderr redirection
2 parents 012580b + 644cb6d commit 260eb49

20 files changed

+176
-27
lines changed

ChangeLog

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Revision history for Rex
55

66
[BUG FIXES]
77
- Detect invalid hostgroup expressions
8+
- Prevent empty log lines upon Rexfile warnings
89

910
[DOCUMENTATION]
1011
- Clarify optional arguments of file commands
@@ -20,6 +21,8 @@ Revision history for Rex
2021
[NEW FEATURES]
2122

2223
[REVISION]
24+
- Fix handling of warnings during Rexfile loading
25+
- Mask internal naming in Rexfile loading output
2326

2427
1.13.4 2021-07-05 Ferenc Erki <[email protected]>
2528
[DOCUMENTATION]

MANIFEST.SKIP

-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ vars\..*
2828
passwd
2929
upload
3030
.*\.conf
31-
.*\.log
3231
^images
3332
projects
3433
Rex\-\d+.*

lib/Rex/CLI.pm

+21-15
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ sub __run__ {
6969
%opts = Rex::Args->getopts;
7070

7171
if ( $opts{'Q'} ) {
72-
my ( $stdout, $stderr );
72+
my $stdout;
7373
open( my $newout, '>', \$stdout );
7474
select $newout;
7575
close(STDERR);
@@ -744,14 +744,11 @@ sub load_rexfile {
744744
}
745745
};
746746

747-
my ( $stdout, $stderr, $default_stderr );
748-
open $default_stderr, ">&", STDERR;
749-
750-
# we close STDERR here because we don't want to see the
751-
# normal perl error message on the screen. Instead we print
752-
# the error message in the catch-if below.
753-
local *STDERR;
754-
open( STDERR, ">>", \$stderr );
747+
# we don't want to see the
748+
# normal perl warning message on the screen. Instead we print
749+
# the warning message in the catch-if below
750+
my @warnings;
751+
local $SIG{__WARN__} = sub { push @warnings, $_[0] };
755752

756753
# we can't use $rexfile here, because if the variable contains dots
757754
# the perl interpreter try to load the file directly without using @INC
@@ -761,13 +758,19 @@ sub load_rexfile {
761758
# update %INC so that we can later use it to find the rexfile
762759
$INC{"__Rexfile__.pm"} = $rexfile;
763760

764-
# reopen STDERR
765-
open STDERR, ">&", $default_stderr;
766-
767-
if ($stderr) {
768-
my @lines = split( $/, $stderr );
761+
if (@warnings) {
769762
Rex::Logger::info( "You have some code warnings:", 'warn' );
770-
Rex::Logger::info( "\t$_", 'warn' ) for @lines;
763+
for (@warnings) {
764+
chomp;
765+
766+
# remove /loader/.../ prefix before filename
767+
s{/loader/[^/]+/}{}sxm;
768+
769+
# convert Rexfile to human-friendly name
770+
s{__Rexfile__.pm}{Rexfile}msx;
771+
772+
Rex::Logger::info( "\t$_", 'warn' );
773+
}
771774
}
772775

773776
1;
@@ -781,6 +784,9 @@ sub load_rexfile {
781784
# we load the Rexfile via our custom code block.
782785
$e =~ s|/loader/[^/]+/||smg;
783786

787+
# convert Rexfile to human-friendly name
788+
$e =~ s{__Rexfile__.pm}{Rexfile}msx;
789+
784790
my @lines = split( $/, $e );
785791

786792
Rex::Logger::info( "Compile time errors:", 'error' );

lib/Rex/Logger.pm

-11
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,6 @@ Setting this variable to 1 will enable debug logging.
6060

6161
our $debug = 0;
6262

63-
# we store the default handle to stderr
64-
# so that we can restore the handle inside the logging functions
65-
my $DEFAULT_STDERR;
66-
open $DEFAULT_STDERR, ">&", STDERR;
67-
6863
=item $silent
6964
7065
If you set this variable to 1 nothing will be logged.
@@ -125,9 +120,6 @@ sub info {
125120

126121
return if $silent;
127122

128-
local *STDERR;
129-
open STDERR, ">&", $DEFAULT_STDERR;
130-
131123
if ( defined($type) ) {
132124
$msg = format_string( $msg, uc($type) );
133125
}
@@ -186,9 +178,6 @@ sub debug {
186178
return if $silent;
187179
return unless $debug;
188180

189-
local *STDERR;
190-
open STDERR, ">&", $DEFAULT_STDERR;
191-
192181
$msg = format_string( $msg, "DEBUG" );
193182

194183
# workaround for windows Sys::Syslog behaviour on forks

t/load_rexfile.t

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#!/usr/bin/env perl
2+
3+
use 5.010001;
4+
use strict;
5+
use warnings;
6+
use autodie;
7+
8+
our $VERSION = '9999.99.99_99'; # VERSION
9+
10+
use Test::More;
11+
12+
use File::Spec;
13+
use File::Temp;
14+
use Rex::CLI;
15+
use Rex::Commands::File;
16+
use Sub::Override;
17+
use Test::Output;
18+
19+
$Rex::Logger::format = '%l - %s';
20+
$Rex::Logger::no_color = 1;
21+
22+
my $testdir = File::Spec->join( 't', 'rexfiles' );
23+
my $rex_cli_path = $INC{'Rex/CLI.pm'};
24+
my $empty = q();
25+
26+
my ( $dh, $exit_was_called, $expected );
27+
28+
my $override =
29+
Sub::Override->new( 'Rex::CLI::exit' => sub { $exit_was_called = 1 } );
30+
31+
my $logfile = File::Temp->new->filename;
32+
Rex::Config->set_log_filename($logfile);
33+
34+
opendir $dh, $testdir;
35+
my @rexfiles = grep { !/[.]/msx } readdir $dh;
36+
closedir $dh;
37+
38+
push @rexfiles, 'no_Rexfile';
39+
40+
plan tests => scalar @rexfiles;
41+
42+
for my $rexfile (@rexfiles) {
43+
subtest "Testing with $rexfile" => sub {
44+
$rexfile = File::Spec->join( $testdir, $rexfile );
45+
46+
_setup_test($rexfile);
47+
48+
output_is { Rex::CLI::load_rexfile($rexfile); } $expected->{stdout},
49+
$expected->{stderr}, 'Expected console output';
50+
51+
is( $exit_was_called, $expected->{exit}, 'Expected exit status' );
52+
is( cat($logfile), $expected->{log}, 'Expected log content' );
53+
};
54+
}
55+
56+
sub _setup_test {
57+
my $rexfile = shift;
58+
59+
Rex::TaskList->create->clear_tasks();
60+
61+
$exit_was_called = 0;
62+
63+
$expected->{exit} = $rexfile =~ qr{fatal}ms ? 1 : 0;
64+
65+
for my $extension (qw(log stdout stderr)) {
66+
my $file = "$rexfile.$extension";
67+
my $default_content = $extension eq 'stderr' ? $expected->{log} : $empty;
68+
69+
$expected->{$extension} = -r $file ? cat($file) : $default_content;
70+
$expected->{$extension} =~ s{%REX_CLI_PATH%}{$rex_cli_path}msx;
71+
}
72+
73+
# reset log
74+
open my $fh, '>', $logfile;
75+
close $fh;
76+
77+
# reset require
78+
delete $INC{'__Rexfile__.pm'};
79+
80+
return;
81+
}

t/rexfiles/Rexfile_fatal

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
use Rex;
2+
3+
abc
4+
5+
task 'test', sub { };

t/rexfiles/Rexfile_fatal.log

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ERROR - Compile time errors:
2+
ERROR - syntax error at Rexfile line 5, near "abc
3+
ERROR -
4+
ERROR - task "
5+
ERROR - Compilation failed in require at %REX_CLI_PATH% line 756.

t/rexfiles/Rexfile_fatal_print

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use Rex;
2+
3+
print STDERR "This is STDERR message\n";
4+
print STDOUT "This is STDOUT message\n";
5+
6+
abc
7+
8+
print STDERR "This is STDERR message\n";
9+
print STDOUT "This is STDOUT message\n";
10+
11+
task 'test', sub { };

t/rexfiles/Rexfile_fatal_print.log

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ERROR - Compile time errors:
2+
ERROR - syntax error at Rexfile line 8, near "abc
3+
ERROR -
4+
ERROR - print"
5+
ERROR - Compilation failed in require at %REX_CLI_PATH% line 756.

t/rexfiles/Rexfile_noerror

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
use Rex;
2+
3+
task 'test', sub { };

t/rexfiles/Rexfile_noerror_print

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
use Rex;
2+
3+
print STDERR "This is STDERR message\n";
4+
print STDOUT "This is STDOUT message\n";
5+
6+
task 'test', sub { };
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is STDERR message
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is STDOUT message

t/rexfiles/Rexfile_warnings

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
use Rex;
2+
3+
use warnings;
4+
5+
warn 'This is warning';
6+
my $warn = 'warn' . undef;
7+
8+
task 'test', sub { };

t/rexfiles/Rexfile_warnings.log

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
WARN - You have some code warnings:
2+
WARN - This is warning at Rexfile line 5.
3+
WARN - Use of uninitialized value in concatenation (.) or string at Rexfile line 6.

t/rexfiles/Rexfile_warnings_print

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use Rex;
2+
3+
use warnings;
4+
5+
warn 'This is warning';
6+
my $warn = 'warn' . undef;
7+
8+
print STDERR "This is STDERR message\n";
9+
print STDOUT "This is STDOUT message\n";
10+
11+
task 'test', sub { };

t/rexfiles/Rexfile_warnings_print.log

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
WARN - You have some code warnings:
2+
WARN - This is warning at Rexfile line 5.
3+
WARN - Use of uninitialized value in concatenation (.) or string at Rexfile line 6.
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
This is STDERR message
2+
WARN - You have some code warnings:
3+
WARN - This is warning at Rexfile line 5.
4+
WARN - Use of uninitialized value in concatenation (.) or string at Rexfile line 6.
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is STDOUT message

t/rexfiles/no_Rexfile.log

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
WARN - No Rexfile found.
2+
WARN - Create a file named 'Rexfile' in this directory,
3+
WARN - or specify the file you want to use with:
4+
WARN - rex -f file_to_use task_to_run

0 commit comments

Comments
 (0)