# New Ticket Created by James Keenan # Please include the string: [perl #52504] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=52504 >
In http://rt.perl.org/rt3/Ticket/Display.html?id=51622, Alberto Simões and I discussed the merits of creating a new configuration step class, to be run on Darwin only, which would detect the installation of Macports in the same way that step class auto::fink detects Fink. The patch attached, ports.patch.txt, implements this plan. Code which was previously duplicated in a number of configuration steps is now consolidated in config/auto/ports.pm and lib/Parrot/Configure/ Step/Methods.pm. I have placed auto::ports immediately after auto::fink in the process. Five tests files are included; these provide 100% coverage of the code in config/auto/ports.pm. Necessary adjustments have been made in MANIFEST and lib/Parrot/Configure/Step/ List.pm as well as three configuration step classes. Please review. I have tested this so far on Darwin and Linux. I'll commit to trunk around mid-week if there are no serious objections. Thank you very much. kid51
Index: lib/Parrot/Configure/Step/List.pm =================================================================== --- lib/Parrot/Configure/Step/List.pm (.../trunk) (revision 26580) +++ lib/Parrot/Configure/Step/List.pm (.../branches/ports) (revision 26788) @@ -21,6 +21,7 @@ auto::gcc auto::backtrace auto::fink + auto::ports auto::msvc auto::attributes auto::warnings Index: lib/Parrot/Configure/Step/Methods.pm =================================================================== --- lib/Parrot/Configure/Step/Methods.pm (.../trunk) (revision 26580) +++ lib/Parrot/Configure/Step/Methods.pm (.../branches/ports) (revision 26788) @@ -83,6 +83,21 @@ return 1; } +sub _handle_darwin_for_macports { + my ($self, $conf, $osname, $file) = @_; + if ( $osname =~ /darwin/ ) { + my $ports_root = $conf->data->get( 'ports_base_dir' ); + my $ports_lib_dir = $conf->data->get( 'ports_lib_dir' ); + my $ports_include_dir = $conf->data->get( 'ports_include_dir' ); + if ( -f qq{$ports_include_dir/$file} ) { + $conf->data->add( ' ', linkflags => "-L$ports_lib_dir" ); + $conf->data->add( ' ', ldflags => "-L$ports_lib_dir" ); + $conf->data->add( ' ', ccflags => "-I$ports_include_dir" ); + } + } + return 1; +} + =back =head1 SEE ALSO Index: t/steps/auto_ports-02.t =================================================================== --- t/steps/auto_ports-02.t (.../trunk) (revision 0) +++ t/steps/auto_ports-02.t (.../branches/ports) (revision 26788) @@ -0,0 +1,82 @@ +#! perl +# Copyright (C) 2007, The Perl Foundation. +# $Id$ +# auto_ports-02.t + +use strict; +use warnings; +use Test::More; +plan( skip_all => 'Macports is Darwin only' ) unless $^O =~ /darwin/; +plan( tests => 12 ); +use Carp; +use lib qw( lib t/configure/testlib ); +use_ok('config::init::defaults'); +use_ok('config::auto::ports'); + +use Parrot::Configure; +use Parrot::Configure::Options qw( process_options ); +use Parrot::Configure::Test qw( test_step_thru_runstep); + +my $args = process_options( { + argv => [], + mode => q{configure}, +} ); + +my $conf = Parrot::Configure->new(); + +test_step_thru_runstep($conf, q{init::defaults}, $args); + +my ($task, $step_name, $step, $ret); +my $pkg = q{auto::ports}; + +$conf->add_steps($pkg); +$conf->options->set(%{$args}); +$task = $conf->steps->[-1]; +$step_name = $task->step; + +$step = $step_name->new(); +ok(defined $step, "$step_name constructor returned defined value"); +isa_ok($step, $step_name); +ok($step->description(), "$step_name has description"); + +# mock no Macports-default directories +$step->{ports_root} = File::Spec->catdir( qw( / my ridiculous foobar ) ); +ok(! defined $step->runstep($conf), "runstep() returned undefined value"); +is($step->result(), 'failed', "Got expected result"); + +pass("Completed all tests in $0"); + +################### DOCUMENTATION ################### + +=head1 NAME + +auto_ports-02.t - test config::auto::ports + +=head1 SYNOPSIS + + % prove t/steps/auto_ports-02.t + +=head1 DESCRIPTION + +The files in this directory test functionality used by F<Configure.pl>. + +The tests in this file test config::auto::ports by mocking the case where +default directories for Macports are not located. + +=head1 AUTHOR + +James E Keenan + +=head1 SEE ALSO + +config::auto::ports, F<Configure.pl>. + +=cut + +# Local Variables: +# mode: cperl +# cperl-indent-level: 4 +# fill-column: 100 +# End: +# vim: expandtab shiftwidth=4: + Property changes on: t/steps/auto_ports-02.t ___________________________________________________________________ Name: svn:eol-style + native Name: svn:mime-type + text/plain Name: svn:keywords + Author Date Id Revision Index: t/steps/auto_ports-03.t =================================================================== --- t/steps/auto_ports-03.t (.../trunk) (revision 0) +++ t/steps/auto_ports-03.t (.../branches/ports) (revision 26788) @@ -0,0 +1,100 @@ +#! perl +# Copyright (C) 2007, The Perl Foundation. +# $Id$ +# auto_ports-03.t + +use strict; +use warnings; +use Test::More; +plan( skip_all => 'Macports is Darwin only' ) unless $^O =~ /darwin/; +plan( tests => 19 ); +use Carp; +use Cwd; +use File::Temp qw( tempdir ); +use lib qw( lib t/configure/testlib ); +use_ok('config::init::defaults'); +use_ok('config::auto::ports'); + +use Parrot::Configure; +use Parrot::Configure::Options qw( process_options ); +use Parrot::Configure::Test qw( test_step_thru_runstep); + +my $args = process_options( { + argv => [], + mode => q{configure}, +} ); + +my $conf = Parrot::Configure->new(); + +test_step_thru_runstep($conf, q{init::defaults}, $args); + +my ($task, $step_name, $step, $ret); +my $pkg = q{auto::ports}; + +$conf->add_steps($pkg); +$conf->options->set(%{$args}); +$task = $conf->steps->[-1]; +$step_name = $task->step; + +$step = $step_name->new(); +ok(defined $step, "$step_name constructor returned defined value"); +isa_ok($step, $step_name); +ok($step->description(), "$step_name has description"); + +my $cwd = cwd(); +{ + my $tdir = tempdir( CLEANUP => 1 ); + $step->{ports_root} = $tdir; + ok(chdir $tdir, "Able to change to temporary directory"); + ok( (mkdir 'lib'), "Able to make lib directory"); + ok( (mkdir 'include'), "Able to make include directory"); + + ok($step->runstep($conf), "runstep() returned true value"); + is($step->result(), q{ports located}, "Got expected result"); + + is($conf->data->get('ports_base_dir'), $tdir, + "ports base directory set as expected"); + is($conf->data->get('ports_lib_dir'), qq{$tdir/lib}, + "ports 'lib' directory set as expected"); + is($conf->data->get('ports_include_dir'), qq{$tdir/include}, + "ports 'include' directory set as expected"); + + ok(chdir $cwd, "Able to change back to original directory after testing"); +} + +pass("Completed all tests in $0"); + +################### DOCUMENTATION ################### + +=head1 NAME + +auto_ports-03.t - test config::auto::ports + +=head1 SYNOPSIS + + % prove t/steps/auto_ports-03.t + +=head1 DESCRIPTION + +The files in this directory test functionality used by F<Configure.pl>. + +The tests in this file test config::auto::ports by mocking the case where +the expected default directories for Macports are found. + +=head1 AUTHOR + +James E Keenan + +=head1 SEE ALSO + +config::auto::ports, F<Configure.pl>. + +=cut + +# Local Variables: +# mode: cperl +# cperl-indent-level: 4 +# fill-column: 100 +# End: +# vim: expandtab shiftwidth=4: + Property changes on: t/steps/auto_ports-03.t ___________________________________________________________________ Name: svn:eol-style + native Name: svn:mime-type + text/plain Name: svn:keywords + Author Date Id Revision Index: t/steps/auto_readline-01.t =================================================================== --- t/steps/auto_readline-01.t (.../trunk) (revision 26580) +++ t/steps/auto_readline-01.t (.../branches/ports) (revision 26788) @@ -134,12 +134,14 @@ { my $tdir3 = File::Spec->canonpath( tempdir( CLEANUP => 1 ) ); ok(chdir $tdir3, "Able to change to temporary directory"); - $step->{macports_root} = $tdir3; ok( (mkdir 'lib'), "Able to make lib directory"); ok( (mkdir 'include'), "Able to make include directory"); - ok( (mkdir 'include/readline'), "Able to make include/readline directory"); my $libdir = File::Spec->catdir( $tdir3, 'lib' ); my $includedir = File::Spec->catdir( $tdir3, 'include' ); + $conf->data->set( ports_base_dir => $tdir3 ); + $conf->data->set( ports_lib_dir => $libdir ); + $conf->data->set( ports_include_dir => $includedir ); + ok( (mkdir 'include/readline'), "Able to make include/readline directory"); my $file = qq{$includedir/readline/readline.h}; open my $FH, ">", $file or croak "Unable to open $file for writing"; print $FH qq{Hello Darwin\n}; @@ -159,12 +161,15 @@ { my $tdir3 = File::Spec->canonpath( tempdir( CLEANUP => 1 ) ); ok(chdir $tdir3, "Able to change to temporary directory"); - $step->{macports_root} = $tdir3; + $step->{ports_root} = $tdir3; ok( (mkdir 'lib'), "Able to make lib directory"); ok( (mkdir 'include'), "Able to make include directory"); - ok( (mkdir 'include/readline'), "Able to make include/readline directory"); my $libdir = File::Spec->catdir( $tdir3, 'lib' ); my $includedir = File::Spec->catdir( $tdir3, 'include' ); + $conf->data->set( ports_base_dir => $tdir3 ); + $conf->data->set( ports_lib_dir => $libdir ); + $conf->data->set( ports_include_dir => $includedir ); + ok( (mkdir 'include/readline'), "Able to make include/readline directory"); my $file = qq{$includedir/readline/readline.h}; $osname = 'darwin'; $flagsbefore = $conf->data->get( 'linkflags' ); Index: t/steps/auto_ports-04.t =================================================================== --- t/steps/auto_ports-04.t (.../trunk) (revision 0) +++ t/steps/auto_ports-04.t (.../branches/ports) (revision 26788) @@ -0,0 +1,91 @@ +#! perl +# Copyright (C) 2007, The Perl Foundation. +# $Id$ +# auto_ports-01.t + +use strict; +use warnings; +use Test::More tests => 13; +use Carp; +use lib qw( lib t/configure/testlib ); +use_ok('config::init::defaults'); +use_ok('config::auto::ports'); + +use Parrot::Configure; +use Parrot::Configure::Options qw( process_options ); +use Parrot::Configure::Test qw( test_step_thru_runstep); +use IO::CaptureOutput qw( capture ); + +my $args = process_options( { + argv => [ q{--verbose} ], + mode => q{configure}, +} ); + +my $conf = Parrot::Configure->new(); + +test_step_thru_runstep($conf, q{init::defaults}, $args); + +my ($task, $step_name, $step, $ret); +my $pkg = q{auto::ports}; + +$conf->add_steps($pkg); +$conf->options->set(%{$args}); +$task = $conf->steps->[-1]; +$step_name = $task->step; + +$step = $step_name->new(); +ok(defined $step, "$step_name constructor returned defined value"); +isa_ok($step, $step_name); +ok($step->description(), "$step_name has description"); + +# mock not Darwin +my $osname = 'foobar'; +$conf->data->set_p5( 'OSNAME' => $osname ); +{ + my ($stdout, $stderr); + my $ret = capture sub { $step->runstep($conf) }, \$stdout, \$stderr; + ok($ret, "runstep() returned true value"); + is($step->result(), q{skipped}, "Got expected result for non-Darwin OS"); + like( + $stdout, + qr/^Operating system is $osname; Macports is Darwin only/, + "Got expected verbose output" + ); +} + +pass("Completed all tests in $0"); + +################### DOCUMENTATION ################### + +=head1 NAME + +auto_ports-01.t - test config::auto::ports + +=head1 SYNOPSIS + + % prove t/steps/auto_ports-01.t + +=head1 DESCRIPTION + +The files in this directory test functionality used by F<Configure.pl>. + +The tests in this file test config::auto::ports in the case where the OS is not +Darwin and verbose output has been requested. + +=head1 AUTHOR + +James E Keenan + +=head1 SEE ALSO + +config::auto::ports, F<Configure.pl>. + +=cut + +# Local Variables: +# mode: cperl +# cperl-indent-level: 4 +# fill-column: 100 +# End: +# vim: expandtab shiftwidth=4: + Property changes on: t/steps/auto_ports-04.t ___________________________________________________________________ Name: svn:eol-style + native Name: svn:mime-type + text/plain Name: svn:keywords + Author Date Id Revision Index: t/steps/auto_ports-01.t =================================================================== --- t/steps/auto_ports-01.t (.../trunk) (revision 0) +++ t/steps/auto_ports-01.t (.../branches/ports) (revision 26788) @@ -0,0 +1,80 @@ +#! perl +# Copyright (C) 2007, The Perl Foundation. +# $Id$ +# auto_ports-01.t + +use strict; +use warnings; +use Test::More tests => 12; +use Carp; +use lib qw( lib t/configure/testlib ); +use_ok('config::init::defaults'); +use_ok('config::auto::ports'); + +use Parrot::Configure; +use Parrot::Configure::Options qw( process_options ); +use Parrot::Configure::Test qw( test_step_thru_runstep); + +my $args = process_options( { + argv => [], + mode => q{configure}, +} ); + +my $conf = Parrot::Configure->new(); + +test_step_thru_runstep($conf, q{init::defaults}, $args); + +my ($task, $step_name, $step, $ret); +my $pkg = q{auto::ports}; + +$conf->add_steps($pkg); +$conf->options->set(%{$args}); +$task = $conf->steps->[-1]; +$step_name = $task->step; + +$step = $step_name->new(); +ok(defined $step, "$step_name constructor returned defined value"); +isa_ok($step, $step_name); +ok($step->description(), "$step_name has description"); + +# mock not Darwin +$conf->data->set_p5( 'OSNAME' => 'foobar' ); +ok($step->runstep($conf), "runstep() returned true value"); +is($step->result(), q{skipped}, "Got expected result for non-Darwin OS"); + +pass("Completed all tests in $0"); + +################### DOCUMENTATION ################### + +=head1 NAME + +auto_ports-01.t - test config::auto::ports + +=head1 SYNOPSIS + + % prove t/steps/auto_ports-01.t + +=head1 DESCRIPTION + +The files in this directory test functionality used by F<Configure.pl>. + +The tests in this file test config::auto::ports in the case where the OS is not +Darwin. + +=head1 AUTHOR + +James E Keenan + +=head1 SEE ALSO + +config::auto::ports, F<Configure.pl>. + +=cut + +# Local Variables: +# mode: cperl +# cperl-indent-level: 4 +# fill-column: 100 +# End: +# vim: expandtab shiftwidth=4: + Property changes on: t/steps/auto_ports-01.t ___________________________________________________________________ Name: svn:eol-style + native Name: svn:mime-type + text/plain Name: svn:keywords + Author Date Id Revision Index: t/steps/auto_ports-05.t =================================================================== --- t/steps/auto_ports-05.t (.../trunk) (revision 0) +++ t/steps/auto_ports-05.t (.../branches/ports) (revision 26788) @@ -0,0 +1,93 @@ +#! perl +# Copyright (C) 2007, The Perl Foundation. +# $Id$ +# auto_ports-05.t + +use strict; +use warnings; +use Test::More; +plan( skip_all => 'Macports is Darwin only' ) unless $^O =~ /darwin/; +plan( tests => 13 ); +use Carp; +use lib qw( lib t/configure/testlib ); +use_ok('config::init::defaults'); +use_ok('config::auto::ports'); + +use Parrot::Configure; +use Parrot::Configure::Options qw( process_options ); +use Parrot::Configure::Test qw( test_step_thru_runstep); +use IO::CaptureOutput qw( capture ); + +my $args = process_options( { + argv => [ q{--verbose} ], + mode => q{configure}, +} ); + +my $conf = Parrot::Configure->new(); + +test_step_thru_runstep($conf, q{init::defaults}, $args); + +my ($task, $step_name, $step, $ret); +my $pkg = q{auto::ports}; + +$conf->add_steps($pkg); +$conf->options->set(%{$args}); +$task = $conf->steps->[-1]; +$step_name = $task->step; + +$step = $step_name->new(); +ok(defined $step, "$step_name constructor returned defined value"); +isa_ok($step, $step_name); +ok($step->description(), "$step_name has description"); + +# mock no Macports-default directories +$step->{ports_root} = File::Spec->catdir( qw( / my ridiculous foobar ) ); +{ + my ($stdout, $stderr); + my $ret = capture sub { $step->runstep($conf) }, \$stdout, \$stderr; + ok(! defined $ret, "runstep() returned undefined value"); + is($step->result(), 'failed', "Got expected result"); + like( + $stdout, + qr/^Could not locate ports directories/, + "Got expected verbose output" + ); +} + +pass("Completed all tests in $0"); + +################### DOCUMENTATION ################### + +=head1 NAME + +auto_ports-05.t - test config::auto::ports + +=head1 SYNOPSIS + + % prove t/steps/auto_ports-05.t + +=head1 DESCRIPTION + +The files in this directory test functionality used by F<Configure.pl>. + +The tests in this file test config::auto::ports by mocking the case where +default directories for Macports are not located and verbose output has been +requested. + +=head1 AUTHOR + +James E Keenan + +=head1 SEE ALSO + +config::auto::ports, F<Configure.pl>. + +=cut + +# Local Variables: +# mode: cperl +# cperl-indent-level: 4 +# fill-column: 100 +# End: +# vim: expandtab shiftwidth=4: + Property changes on: t/steps/auto_ports-05.t ___________________________________________________________________ Name: svn:eol-style + native Name: svn:mime-type + text/plain Name: svn:keywords + Author Date Id Revision Index: config/auto/gmp.pm =================================================================== --- config/auto/gmp.pm (.../trunk) (revision 26580) +++ config/auto/gmp.pm (.../branches/ports) (revision 26788) @@ -34,7 +34,6 @@ my %data; $data{description} = q{Determining if your platform supports GMP}; $data{result} = q{}; - $data{macports_root} = File::Spec->catdir( '/', 'opt', 'local' ); $data{cc_run_expected} = "6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151 0\n"; @@ -69,11 +68,8 @@ # On OS X check the presence of the gmp header in the standard # Fink location. $self->_handle_darwin_for_fink($conf, $osname, 'gmp.h'); + $self->_handle_darwin_for_macports($conf, $osname, 'gmp.h'); - # Probably this should be moved to an independent place as - # it is replicated in config/auto/readline.pm - $self->_handle_darwin_for_macports($conf,$osname,'gmp.h'); - $conf->cc_gen('config/auto/gmp/gmp.in'); eval { $conf->cc_build(); }; my $has_gmp = 0; @@ -89,23 +85,6 @@ return 1; } -sub _handle_darwin_for_macports { - my $self = shift; - my ($conf, $osname, $file) = @_; - if ( $osname =~ /darwin/ ) { - my $macports_root = $self->{macports_root}; - my $macports_lib_dir = qq{$macports_root/lib}; - my $macports_include_dir = qq{$macports_root/include}; - if ( -f qq{$macports_include_dir/$file} ) { - $conf->data->add( ' ', linkflags => "-L$macports_lib_dir" ); - $conf->data->add( ' ', ldflags => "-L$macports_lib_dir" ); - $conf->data->add( ' ', ccflags => "-I$macports_include_dir" ); - } - } - return 1; -} - - sub _handle_mswin32 { my ($conf, $osname, $cc) = @_; if ( $osname =~ /mswin32/i ) { Index: config/auto/ports.pm =================================================================== --- config/auto/ports.pm (.../trunk) (revision 0) +++ config/auto/ports.pm (.../branches/ports) (revision 26788) @@ -0,0 +1,93 @@ +# Copyright (C) 2005-2007, The Perl Foundation. +# $Id$ + +=head1 NAME + +config/auto/ports.pm - Determine Macports location on Darwin + +=head1 DESCRIPTION + +If the operating system is Darwin, this class determines whether or not +Macports is installed in the default location. + +B<Note:> No provision is yet made for Macports installation in non-default +locations. + +B<Note:> This step is currently Darwin/Macports-specific because it +consolidates code previously found in multiple configuration step classes. +With some modification it may be suitable for application to BSD F<ports> +programs in general, but as there was no BSD-specific code in the +configuration step classes, that modification has not yet been made. + +=cut + +package auto::ports; + +use strict; +use warnings; + +use File::Spec; +use base qw(Parrot::Configure::Step); + +use Parrot::Configure::Utils ':auto'; +use Parrot::BuildUtil; + + +sub _init { + my $self = shift; + my %data; + $data{description} = q{Determining Macports location on Darwin}; + $data{result} = q{}; + $data{ports_root} = File::Spec->catdir( '/', 'opt', 'local' ); + return \%data; +} + +sub runstep { + my ( $self, $conf ) = ( shift, shift ); + my $osname = $conf->data->get_p5( 'OSNAME' ); + my $verbose = $conf->options->get( 'verbose' ); + unless ($osname =~ /darwin/) { + print "Operating system is $osname; Macports is Darwin only\n" + if $verbose; + $self->set_result('skipped'); + return 1; + } + my $ports_base_dir = $self->{ports_root}; + my $ports_lib_dir = qq{$ports_base_dir/lib}; + my $ports_include_dir = qq{$ports_base_dir/include}; + my @unlocateables; + foreach my $dir ($ports_base_dir, $ports_lib_dir, $ports_include_dir) { + push @unlocateables, $dir unless (-d $dir); + } + if (@unlocateables) { + print "Could not locate ports directories: @unlocateables\n" + if $verbose; + $self->set_result('failed'); + return; + } + else { + $conf->data->set( + ports_base_dir => $ports_base_dir, + ports_lib_dir => $ports_lib_dir, + ports_include_dir => $ports_include_dir, + ); + $self->set_result('ports located'); + return 1; + } +} + +1; + +=head1 AUTHOR + +James E Keenan, consolidating code written by Alberto SimÃes, Leopold Toetsch +and others. + +=cut + +# Local Variables: +# mode: cperl +# cperl-indent-level: 4 +# fill-column: 100 +# End: +# vim: expandtab shiftwidth=4: Property changes on: config/auto/ports.pm ___________________________________________________________________ Name: svn:eol-style + native Name: svn:keywords + Author Date Id Revision Index: config/auto/readline.pm =================================================================== --- config/auto/readline.pm (.../trunk) (revision 26580) +++ config/auto/readline.pm (.../branches/ports) (revision 26788) @@ -30,7 +30,6 @@ my %data; $data{description} = q{Determining if your platform supports readline}; $data{result} = q{}; - $data{macports_root} = File::Spec->catdir( '/', 'opt', 'local' ); return \%data; } @@ -51,12 +50,6 @@ # On OS X check the presence of the readline header in the standard # Fink/macports locations. $self->_handle_darwin_for_fink($conf, $osname, 'readline/readline.h'); - - # Since this config step class is the only one that checks for a - # macports-installed program, we have not yet had need to create an - # 'auto::macports' config step and do not yet have enough basis to extract - # this code into a Parrot::Configure::Step::Methods method analogous to - # _handle_darwin_for_fink(). $self->_handle_darwin_for_macports($conf, $osname, q{readline/readline.h}); $conf->cc_gen('config/auto/readline/readline.in'); @@ -93,22 +86,6 @@ return 1; } -sub _handle_darwin_for_macports { - my $self = shift; - my ($conf, $osname, $file) = @_; - if ( $osname =~ /darwin/ ) { - my $macports_root = $self->{macports_root}; - my $macports_lib_dir = qq{$macports_root/lib}; - my $macports_include_dir = qq{$macports_root/include}; - if ( -f qq{$macports_include_dir/$file} ) { - $conf->data->add( ' ', linkflags => "-L$macports_lib_dir" ); - $conf->data->add( ' ', ldflags => "-L$macports_lib_dir" ); - $conf->data->add( ' ', ccflags => "-I$macports_include_dir" ); - } - } - return 1; -} - sub _evaluate_cc_run { my ($self, $verbose) = @_; my $has_readline = 1;