#!/usr/bin/env perl use 5.012; use warnings; # run script on the first line and compare its output to remaining lines my $regenerate = @ARGV > 1 && $ARGV[0] eq '-G' && shift; @ARGV or die "missing input script\n"; !!(my $spec = readline) or die "input lacks a script on the first line\n"; my $script = $spec; chomp $script; my $wantexit = $script =~ s/\h+[?](\d+)\z// ? $1 : 0; my $wantwarn = $script !~ s/[?]\z//; my $shell = $script; if ($script =~ /\|/) { # explicit shell wrapper to capture all warnings $script =~ s/'/'\\''/g; $shell = "sh -c '$shell'"; } $shell .= ' 2>&1' if $wantwarn; local $ENV{COLUMNS} = 40; open my $cmd, '-|', $shell or do { say "cannot run script `$script`: $!"; exit 2; }; my @lines = readline $cmd; close $cmd; my $error = $? >> 8; if ($regenerate) { open my $rewrite, '>', $ARGV; print {$rewrite} $_ for $spec, @lines; exit; } if ($error != $wantexit) { say "unexpected exit status $error for `$script`"; exit 2; } my @wanted = readline; my $diff = 0; while (@lines or @wanted) { my $was = shift @wanted; my $is = shift @lines; next if defined $was and defined $is and $was eq $is; $diff++; print color(32), "< ", color(0), $_ for $was // (); print color(31), "> ", color(0), $_ for $is // (); } exit($diff > 0); sub color { return "\e[@{_}m"; }