I'd like to get some feedback on this commit regard platform
interoperability.
I could only test it on linux, so I'm not sure what could break.
(One comment inline in the diff below)
[EMAIL PROTECTED] wrote:
> Author: moritz
> Date: Wed Jul 2 03:34:59 2008
> New Revision: 28944
>
> Added:
> trunk/languages/perl6/tools/autounfudge.pl (contents, props changed)
> Modified:
> trunk/MANIFEST
>
> Log:
> [rakudo] add tools/autounfudge.pl
>
>
> Modified: trunk/MANIFEST
> ==============================================================================
> --- trunk/MANIFEST (original)
> +++ trunk/MANIFEST Wed Jul 2 03:34:59 2008
> @@ -1,7 +1,7 @@
> # ex: set ro:
> # $Id$
> #
> -# generated by tools/dev/mk_manifest_and_skip.pl Wed Jul 2 08:40:48 2008 UT
> +# generated by tools/dev/mk_manifest_and_skip.pl Wed Jul 2 10:46:48 2008 UT
> #
> # See tools/dev/install_files.pl for documentation on the
> # format of this file.
> @@ -2002,6 +2002,7 @@
> languages/perl6/t/pmc/mutable.t [perl6]
> languages/perl6/t/pmc/mutablevar.t [perl6]
> languages/perl6/t/spectest_regression.data [perl6]
> +languages/perl6/tools/autounfudge.pl [perl6]
> languages/perl6/tools/fudge_purity_inspector.pl [perl6]
> languages/perl6/tools/progress-graph.pl [perl6]
> languages/perl6/tools/test_summary.pl [perl6]
>
> Added: trunk/languages/perl6/tools/autounfudge.pl
> ==============================================================================
> --- (empty file)
> +++ trunk/languages/perl6/tools/autounfudge.pl Wed Jul 2 03:34:59 2008
> @@ -0,0 +1,212 @@
> +#! perl
> +# Copyright (C) 2008, The Perl Foundation.
> +# $Id$
> +
> +=head1 NAME
> +
> +autounfudge - automatically write patches for unfudging spec tests
> +
> +=head1 DESCRIPTION
> +
> +This tool runs the non-pure tests of the C<spectest_regression> make target,
> +automatically creates files with less fudges, runs them again, and if the
> +modified tests succeeds, it adds a patch to C<autounfudge.patch> that, when
> +applied as C<< patch -p0 < autunfudge.patch >>, removes the superflous fudge
> +directives.
> +
> +=head1 USAGE
> +
> +Most common usage: C<perl tools/autounfudge.pl --auto>. For more use cases
> +pleae run this script without any options or command line parameters.
> +
> +=head1 WARNINGS
> +
> +This tool is very platform dependant, and not tested on anthing but linux.
> +
> +It assumes that all fudge directives are orthogonal, which might not be the
> +case in real world tests. It is not tested with nested fudges (eg a line
> +based fudge inside a fudged block).
> +
> +Never blindly apply the automatically generated patch.
> +
> +=head1 MISCELANEA
> +
> +Fudge directives containing the words I<unspecced> or I<unicode> are ignored.
> +The latter is because Unicode related tests can succeed on platforms with icu
> +installed, and fail on other platforms.
> +
> +=cut
> +
> +use strict;
> +use warnings;
> +use Getopt::Long;
> +use Fatal qw(close);
> +use File::Temp qw(tempfile tempdir);
> +use TAP::Harness;
> +use TAP::Parser::Aggregator;
> +use Cwd qw(getcwd);
> +use File::Spec;
> +use File::Path;
> +
> +my $impl = 'rakudo';
> +our $debug = 0;
> +our $out_filename = 'autounfudge.patch';
> +
> +if ($^O ne 'linux'){
> + warn <<'WARN';
> +Warning: this tool is only tested on linux so far. Currently it depends on
> +some linux specific hacks. It requires the `diff' program to be installed.
> +If you test this on any platform other than linux, pleaes report your results
> +to [EMAIL PROTECTED]
> +WARN
> +}
> +
> +GetOptions 'impl=s' => \$impl,
> + 'debug' => \$debug,
> + 'specfile=s' => \my $specfile,
> + 'auto' => \my $auto,
> + or usage();
> +my @files;
> +
> +$specfile = 't/spectest_regression.data' if $auto;
> +
> +if ($specfile){
> + @files = read_specfile($specfile);
> +}
> +else {
> + @files = @ARGV or usage();
> +}
> +
> +if (-e $out_filename){
> + unlink $out_filename or warn "Couldn't delete old unfudge.patch";
> +}
> +our $tmp_dir = tempdir('RAKUDOXXXXXX', CLEANUP => 1);
> +
> +for (@files){
> + auto_unfudge_file($_);
> +}
> +
> +sub auto_unfudge_file {
> + my $file_name = shift;
> + open my $f, '<:encoding(UTF-8)', $file_name
> + or die "Can't open '$file_name' for reading: $!";
> + print "Processing file '$file_name'\n";
> + my @fudge_lines;
> + while (<$f>) {
> + push @fudge_lines, $. if m/^\s*#\?$impl/ &&
> + !m/unspecced|unicode|utf-?8/i;
> + }
> + close $f;
> + if (@fudge_lines){
> + print "Found " . (scalar @fudge_lines) . " fudges...\n" if $debug;
> + }
> + else {
> + print "No fudges found. Nothing to do\n" if $debug;
> + return;
> + }
> + my $fudged = fudge($file_name);
> + print "Fudged: $fudged\n" if $debug;
> + if (!tests_ok($fudged)){
> + print "File '$file_name' doesn't even pass in its current state\n";
> + return;
> + }
> + my @to_unfudge;
> + for my $to_unfudge (@fudge_lines){
> + $fudged = fudge(unfudge_some($file_name, 0, $to_unfudge));
> + if (tests_ok($fudged)){
> + print "WOOOOOT: Can remove fudge instruction on line
> $to_unfudge\n"
> + if $debug;
> + push @to_unfudge, $to_unfudge,
> + }
> + }
> +
> + if (@to_unfudge){
> + my $u = unfudge_some($file_name, 1, @to_unfudge);
> + system qq{diff -u "$file_name" "$u" >> "$out_filename"};
This is the line that troubles me most. Will that work on Windows and
MacOS? If not, how could I improve it?
> + unlink $u;
> + }
> +
> +}
> +
> +sub fudge {
> + my $fn = shift;
> + open my $p, '-|', 't/spec/fudge', '--keep-exit-code', $impl, $fn
> + or die "Can't launch fudge: $!";
> + my $ret_fn = <$p>;
> + chomp $ret_fn;
> + 1 while <$p>;
> + close $p;
> + return $ret_fn;
> +}
> +
> +sub usage {
> + die <<"USAGE"
> +Usage:
> + $0 [options] file+
> +Valid options:
> + --debug Enable debug output
> + --impl impl Specify a different implementation
> + --specfile file Specification file to read filenames from
> + --auto use t/spectest_regression.data for --specfile
> +USAGE
> +}
> +
> +sub unfudge_some {
> + my ($file, $delete, @lines) = @_;
> + my ($fh, $tmp_filename) = tempfile(
> + 'tempXXXXX',
> + SUFFIX => '.t',
> + DIR => $tmp_dir
> + );
> + open my $in, '<', $file
> + or die "Can't open file '$file' for reading: $!";
> + while (<$in>){
> + if ($. == $lines[0]){
> + print $fh "###$_" unless $delete;
> + shift @lines if @lines > 1;
> + }
> + else {
> + print $fh $_;
> + }
> + }
> + close $fh;
> + close $in;
> + return $tmp_filename;
> +}
> +
> +sub tests_ok {
> + my $fn = shift;
> + $fn =~ s/\s+\z//;
> + my $harness = get_harness();
> + my $agg = TAP::Parser::Aggregator->new();
> + $agg->start();
> + $harness->aggregate_tests($agg, $fn);
> + $agg->stop();
> +# my $agg = $harness->runtests($fn);
> + return !$agg->has_errors;
> +}
> +
> +sub get_harness {
> + return TAP::Harness->new({
> + verbosity => -2,
> + exec => ['../../parrot', '-G', 'perl6.pbc'],
> + merge => 1,
> + });
> +}
> +
> +sub read_specfile {
> + my $fn = shift;
> + my @res;
> + open (my $f, '<', $fn) or die "Can't open file '$fn' for reading: $!";
> + while (<$f>){
> + next if m/#/;
> + next unless m/\S/;
> + s/\s+\z//;
> + push @res, "t/spec/$_";
> + }
> + return @res;
> +}
> +
> +END {
> + File::Path::rmtree($tmp_dir);
> +}
--
Moritz Lenz
http://moritz.faui2k3.org/ | http://perl-6.de/