Thread: [Module-build-general] [PATCH] ./Build ppd codebase=...
Status: Beta
Brought to you by:
kwilliams
|
From: Dave R. <au...@ur...> - 2003-04-24 20:32:03
|
This patch adds support a "Build ppd" action, along with tests for it. The PPD generating code is mostly from EU::MM_Unix in the 6.10_03 distro, except that I don't add the OS or ARCHITECTURE tags unless the module includes XS, though I really don't know if that's right. I also updated a few attribute names based on the spec at http://www.xav.com/perl/site/lib/XML/PPD.html The patch also refactors several bits of code so that the ACTION_ppd method didn't have too much cut'n'pasted code in it. It adds two new properties, 'author' and 'abstract', though the latter can be determined by looking at a module's docs if it isn't given. There's no docs in the patch, but I'd be happy to do that if the patch is accepted. Patch after sig. -dave /*======================= House Absolute Consulting www.houseabsolute.com =======================*/ ? t/XSTest/lib/XSTest.bs ? t/XSTest/lib/XSTest.c Index: lib/Module/Build/Base.pm =================================================================== RCS file: /cvsroot/module-build/Module-Build/lib/Module/Build/Base.pm,v retrieving revision 1.97 diff -u -r1.97 Base.pm --- lib/Module/Build/Base.pm 24 Apr 2003 16:23:52 -0000 1.97 +++ lib/Module/Build/Base.pm 24 Apr 2003 20:27:00 -0000 @@ -198,6 +198,9 @@ verbose c_source autosplit + + author + abstract ); sub valid_property { exists $valid_properties{$_[1]} } @@ -436,10 +439,7 @@ my %status = (need => $spec); if ($modname eq 'perl') { - # Check the current perl interpreter - # It's much more convenient to use $] here than $^V, but 'man - # perlvar' says I'm not supposed to. Bloody tyrant. - $status{have} = $^V ? $self->perl_version_to_float(sprintf "%vd", $^V) : $]; + $status{have} = $self->_find_perl_version; } else { my $file = $self->find_module_by_name($modname, \@INC); @@ -455,12 +455,7 @@ } } - my @conditions; - if ($spec =~ /^\s*([\w.]+)\s*$/) { # A plain number, maybe with dots, letters, and underscores - @conditions = (">= $spec"); - } else { - @conditions = split /\s*,\s*/, $spec; - } + my @conditions = $self->_parse_conditions($spec); foreach (@conditions) { unless ( /^\s* (<=?|>=?|==|!=) \s* ([\w.]+) \s*$/x ) { @@ -481,6 +476,24 @@ return \%status; } +sub _find_perl_version { + my ($self) = @_; + # Check the current perl interpreter + # It's much more convenient to use $] here than $^V, but 'man + # perlvar' says I'm not supposed to. Bloody tyrant. + return $^V ? $self->perl_version_to_float(sprintf "%vd", $^V) : $]; +} + +sub _parse_conditions { + my($self, $spec) = @_; + + if ($spec =~ /^\s*([\w.]+)\s*$/) { # A plain number, maybe with dots, letters, and underscores + return (">= $spec"); + } else { + return split /\s*,\s*/, $spec; + } +} + # I wish I could set $! to a string, but I can't, so I use $@ sub check_installed_version { my ($self, $modname, $spec) = @_; @@ -611,7 +624,12 @@ my ($action, %args); foreach (@_) { if ( /^(\w+)=(.*)/ ) { - $args{$1} = $2; + if ( exists $args{$1} ) { + $args{$1} = [ $args{$1} ] unless ref $args{$1}; + push @{$args{$1}}, $2; + } else { + $args{$1} = $2; + } } elsif ( /^(\w+)$/ ) { die "Error: multiple build actions given: '$action' and '$1'" if $action; $action = $1; @@ -1070,6 +1088,152 @@ require ExtUtils::Manifest; # ExtUtils::Manifest is not warnings clean. local ($^W, $ExtUtils::Manifest::Quiet) = (0,1); ExtUtils::Manifest::mkmanifest(); +} + +# This code is mostly borrowed from ExtUtils::MM_Unix 6.10_03, with a +# few tweaks based on the PPD spec at +# http://www.xav.com/perl/site/lib/XML/PPD.html +sub ACTION_ppd { + my ($self) = @_; + + unless (exists $self->{args}{codebase}) { + warn "Cannot create a PPD file unless codebase argument is given\n"; + return; + } + + $self->find_version; + my $version = $self->_ppd_version($self->{properties}{dist_version}); + + my $abstract = $self->{properties}{abstract}; + + unless (defined $abstract) { + $abstract = $self->_parse_abstract($self->{properties}{dist_version_from}); + } + + $abstract = '' unless defined $abstract; + + my $author = + defined $self->{properties}{author} ? $self->{properties}{author} : ''; + + $self->_simple_xml_escape($_) for ($abstract, $author); + + # could add <LICENSE HREF=...> tag if we knew what the URLs were for + # various licenses + my $ppd = sprintf(<<'EOF', $self->{properties}{dist_name}, $version, $self->{properties}{dist_name}, $abstract, $author); +<SOFTPKG NAME="%s" VERSION="%s"> + <TITLE>%s</TITLE> + <ABSTRACT>%s</ABSTRACT> + <AUTHOR>%s</AUTHOR> + <IMPLEMENTATION> +EOF + + foreach my $type (qw(requires recommends build_requires)) { + while (my ($modname, $spec) = each %{$self->{properties}{$type}}) { + next if $modname eq 'perl'; + + my $min_version = '0.0'; + foreach my $c ($self->_parse_conditions($spec)) { + my ($op, $version) = $c =~ /^\s* (<=?|>=?|==|!=) \s* ([\w.]+) \s*$/x; + + # This is a nasty hack because it fails if there is no >= op + if ($op eq '>=') { + $min_version = $version; + last; + } + } + + $modname =~ s/::/-/g; + + # Another hack because we treat everything as a plain dependency + $ppd .= sprintf(<<'EOF', $modname, $self->_ppd_version($min_version)); + <DEPENDENCY NAME="%s" VERSION="%s" /> +EOF + + } + } + + # We only include these tags if this module involves XS, on the + # assumption that pure Perl modules will work on any OS. PERLCORE, + # unfortunately, seems to indicate that a module works with _only_ + # that version of Perl, and so is only appropriate when a module + # uses XS. + if (@{$self->find_xs_files}) { + my $perl_version = $self->_ppd_version($self->_find_perl_version); + $ppd .= sprintf(<<'EOF', $perl_version, $^O, $self->{config}{archname}); + <PERLCORE VERSION="%s" /> + <OS VALUE="%s" /> + <ARCHITECTURE NAME="%s" /> +EOF + } + + foreach my $codebase (ref $self->{args}{codebase} ? + @{$self->{args}{codebase}} : + $self->{args}{codebase} ) { + $self->_simple_xml_escape($codebase); + $ppd .= sprintf(<<'EOF', $codebase); + <CODEBASE HREF="%s" /> +EOF + } + + $ppd .= <<'EOF'; + </IMPLEMENTATION> +</SOFTPKG> +EOF + + my $ppd_file = "$self->{properties}{dist_name}.ppd"; + my $fh = IO::File->new(">$ppd_file") + or die "Cannot write to $ppd_file: $!"; + print $fh $ppd; + close $fh; + + $self->add_to_cleanup($ppd_file); +} + +sub _parse_abstract { + my($self, $file) = @_; + + my $result; + local $/ = "\n"; + + my $fh = IO::File->new("<$file") + or die "Could not open $file: $!"; + + my $package = $self->{properties}{dist_name}; + $package =~ s/-/::/g; + + my $inpod = 0; + while (<$fh>) { + $inpod = /^=(?!cut)/ ? 1 : /^=cut/ ? 0 : $inpod; + + next unless $inpod; + + chomp; + + next unless /^($package\s-\s)(.*)/; + + $result = $2; + last; + } + close $fh; + + return $result; +} + +sub _ppd_version { + my ($self, $version) = @_; + + # generates something like "0,18,0,0" + return join ',', (split(/\./, $version), (0)x4)[0..3]; +} + +sub _simple_xml_escape { + my ($self) = @_; + + $_[1] =~ s/\n/\\n/sg; + $_[1] =~ s/\"/"/g; + $_[1] =~ s/&/&/g; + $_[1] =~ s/</</g; + $_[1] =~ s/>/>/g; } sub dist_dir { Index: t/runthrough.t =================================================================== RCS file: /cvsroot/module-build/Module-Build/t/runthrough.t,v retrieving revision 1.17 diff -u -r1.17 runthrough.t --- t/runthrough.t 24 Apr 2003 16:24:35 -0000 1.17 +++ t/runthrough.t 24 Apr 2003 20:27:00 -0000 @@ -1,5 +1,7 @@ +use strict; + use Test; -BEGIN { plan tests => 17 } +BEGIN { plan tests => 18 } use Module::Build; use File::Spec; use File::Path; @@ -20,6 +22,9 @@ chdir $goto or die "can't chdir to $goto: $!"; my $build = new Module::Build( module_name => 'Sample', scripts => [ 'script' ], + requires => {'Module::Build' => 0.05}, + author => 'Sample Author', + abstract => 'Sample Abstract', license => 'perl' ); ok $build; @@ -101,6 +106,28 @@ ok $first_line ne "#!perl -w\n"; } + +{ + $build->dispatch('ppd', args => {codebase => '/path/to/codebase'}); + + my $ppd = slurp('Sample.ppd'); + + # This test is quite a hack since with XML you don't really want to + # do a strict string comparison, but absent an XML parser it's the + # best we can do. + ok $ppd, <<'EOF'; +<SOFTPKG NAME="Sample" VERSION="0,01,0,0"> + <TITLE>Sample</TITLE> + <ABSTRACT>Sample Abstract</ABSTRACT> + <AUTHOR>Sample Author</AUTHOR> + <IMPLEMENTATION> + <DEPENDENCY NAME="Module-Build" VERSION="0,05,0,0" /> + <CODEBASE HREF="/path/to/codebase" /> + </IMPLEMENTATION> +</SOFTPKG> +EOF +} + eval {$build->dispatch('realclean')}; ok $@, ''; Index: t/xs.t =================================================================== RCS file: /cvsroot/module-build/Module-Build/t/xs.t,v retrieving revision 1.5 diff -u -r1.5 xs.t --- t/xs.t 24 Feb 2003 18:23:20 -0000 1.5 +++ t/xs.t 24 Apr 2003 20:27:00 -0000 @@ -4,12 +4,15 @@ use Test; print("1..0 # Skipped: no compiler found\n"), exit(0) unless have_compiler(); -plan tests => 7; +plan tests => 8; +use Config; use Module::Build; use File::Spec; ok(1); +require File::Spec->catfile('t', 'common.pl'); + ######################### End of black magic. # Pretend we're in the t/XSTest/ subdirectory @@ -19,6 +22,7 @@ my $m = new Module::Build ( module_name => 'XSTest', + author => 'XSTest Author', ); ok(1); @@ -31,6 +35,31 @@ # We can't be verbose in the sub-test, because Test::Harness will think that the output is for the top-level test. eval {$m->dispatch('test')}; ok $@, ''; + +{ + $m->dispatch('ppd', args => {codebase => '/path/to/codebase-xs'}); + + my $ppd = slurp('XSTest.ppd'); + + my $perl_version = $m->_ppd_version($m->_find_perl_version); + + # This test is quite a hack since with XML you don't really want to + # do a strict string comparison, but absent an XML parser it's the + # best we can do. + ok $ppd, <<"EOF"; +<SOFTPKG NAME="XSTest" VERSION="0,01,0,0"> + <TITLE>XSTest</TITLE> + <ABSTRACT>Perl extension for blah blah blah</ABSTRACT> + <AUTHOR>XSTest Author</AUTHOR> + <IMPLEMENTATION> + <PERLCORE VERSION="$perl_version" /> + <OS VALUE="$^O" /> + <ARCHITECTURE NAME="$Config{archname}" /> + <CODEBASE HREF="/path/to/codebase-xs" /> + </IMPLEMENTATION> +</SOFTPKG> +EOF +} eval {$m->dispatch('realclean')}; ok $@, ''; |
|
From: Ken W. <ke...@ma...> - 2003-04-24 21:43:19
|
Ooh, cool. I'll most likely apply this sometime this weekend. -Ken On Thursday, April 24, 2003, at 03:30 PM, Dave Rolsky wrote: > This patch adds support a "Build ppd" action, along with tests for it. > The PPD generating code is mostly from EU::MM_Unix in the 6.10_03 > distro, > except that I don't add the OS or ARCHITECTURE tags unless the module > includes XS, though I really don't know if that's right. > > I also updated a few attribute names based on the spec at > http://www.xav.com/perl/site/lib/XML/PPD.html > > The patch also refactors several bits of code so that the ACTION_ppd > method didn't have too much cut'n'pasted code in it. > > It adds two new properties, 'author' and 'abstract', though the latter > can > be determined by looking at a module's docs if it isn't given. > > There's no docs in the patch, but I'd be happy to do that if the patch > is > accepted. > > Patch after sig. > > > -dave |
|
From: Ken W. <ke...@ma...> - 2003-05-09 22:30:48
|
On Thursday, April 24, 2003, at 03:30 PM, Dave Rolsky wrote: > This patch adds support a "Build ppd" action, along with tests for it. > The PPD generating code is mostly from EU::MM_Unix in the 6.10_03 > distro, > except that I don't add the OS or ARCHITECTURE tags unless the module > includes XS, though I really don't know if that's right. > I've committed this with a bunch of changes. I put most of the code into a new Module::Build::PPMMaker module. Care to try it out? -Ken |
|
From: Dave R. <au...@ur...> - 2003-05-09 22:55:57
|
On Fri, 9 May 2003, Ken Williams wrote: > I've committed this with a bunch of changes. I put most of the code > into a new Module::Build::PPMMaker module. No, actually you put it in a file called PPD.pm, so it can't find it ;) > Care to try it out? Patch after sig ;) -dave /*======================= House Absolute Consulting www.houseabsolute.com =======================*/ Index: lib/Module/Build/Base.pm =================================================================== RCS file: /cvsroot/module-build/Module-Build/lib/Module/Build/Base.pm,v retrieving revision 1.116 diff -u -r1.116 Base.pm --- lib/Module/Build/Base.pm 9 May 2003 22:28:53 -0000 1.116 +++ lib/Module/Build/Base.pm 9 May 2003 22:54:29 -0000 @@ -1104,8 +1104,8 @@ sub ACTION_ppd { my ($self) = @_; - require Module::Build::PPMMaker; - my $ppd = Module::Build::PPMMaker->new(archname => $self->{config}{archname}); + require Module::Build::PPD; + my $ppd = Module::Build::PPD->new(archname => $self->{config}{archname}); my $file = $ppd->make_ppd(%{$self->{args}}, build => $self); $self->add_to_cleanup($file); } Index: lib/Module/Build/PPD.pm =================================================================== RCS file: /cvsroot/module-build/Module-Build/lib/Module/Build/PPD.pm,v retrieving revision 1.1 diff -u -r1.1 PPD.pm --- lib/Module/Build/PPD.pm 9 May 2003 21:17:40 -0000 1.1 +++ lib/Module/Build/PPD.pm 9 May 2003 22:54:30 -0000 @@ -1,4 +1,4 @@ -package Module::Build::PPMMaker; +package Module::Build::PPD; use strict; @@ -74,7 +74,7 @@ # unfortunately, seems to indicate that a module works with _only_ # that version of Perl, and so is only appropriate when a module # uses XS. - if (keys %{$self->find_xs_files}) { + if (keys %{$build->find_xs_files}) { my $perl_version = $self->_ppd_version($build->perl_version); $ppd .= sprintf(<<'EOF', $perl_version, $^O, $self->{archname}); <PERLCORE VERSION="%s" /> @@ -144,7 +144,7 @@ =head1 NAME -Module::Build::PPMMaker - Perl Package Manager file creation +Module::Build::PPD - Perl Package Manager file creation =head1 SYNOPSIS Index: t/xs.t =================================================================== RCS file: /cvsroot/module-build/Module-Build/t/xs.t,v retrieving revision 1.7 diff -u -r1.7 xs.t --- t/xs.t 9 May 2003 22:29:13 -0000 1.7 +++ t/xs.t 9 May 2003 22:54:30 -0000 @@ -41,7 +41,7 @@ my $ppd = slurp('XSTest.ppd'); - my $perl_version = Module::Build::PPMMaker->_ppd_version($m->perl_version); + my $perl_version = Module::Build::PPD->_ppd_version($m->perl_version); # This test is quite a hack since with XML you don't really want to # do a strict string comparison, but absent an XML parser it's the |
|
From: Ken W. <ke...@ma...> - 2003-05-10 17:41:23
|
On Friday, May 9, 2003, at 05:54 PM, Dave Rolsky wrote: > On Fri, 9 May 2003, Ken Williams wrote: > >> I've committed this with a bunch of changes. I put most of the code >> into a new Module::Build::PPMMaker module. > > No, actually you put it in a file called PPD.pm, so it can't find it ;) Erm, I really did mean to do PPMMaker, but didn't commit the name change. Try again now (also a couple other bugs fixed, I think). -Ken |
|
From: Dave R. <au...@ur...> - 2003-05-10 18:12:03
|
On Sat, 10 May 2003, Ken Williams wrote: > > On Friday, May 9, 2003, at 05:54 PM, Dave Rolsky wrote: > > > On Fri, 9 May 2003, Ken Williams wrote: > > > >> I've committed this with a bunch of changes. I put most of the code > >> into a new Module::Build::PPMMaker module. > > > > No, actually you put it in a file called PPD.pm, so it can't find it ;) > > Erm, I really did mean to do PPMMaker, but didn't commit the name > change. Try again now (also a couple other bugs fixed, I think). I think it gets too much stuff when looking for the author (try it on Module::Build to see). A patch to reduce this is below. /*======================= House Absolute Consulting www.houseabsolute.com =======================*/ --- Base.pm.~1.116.~ 2003-05-10 13:03:57.000000000 -0500 +++ Base.pm 2003-05-10 13:10:24.000000000 -0500 @@ -290,11 +290,12 @@ my @author; while (<$fh>) { next unless /^=head1\s+AUTHOR/ ... /^=/; - push @author, $_; + push @author, $_ if /\S/ && ! /^=/; + last if @author && /\n|\r/; } return unless @author; - my $author = join '', @author[1..$#author-1]; + my $author = join '', @author; $author =~ s/^\s+|\s+$//g; return $p->{dist_author} = $author; } |
|
From: Ken W. <ke...@ma...> - 2003-05-10 21:06:46
|
On Saturday, May 10, 2003, at 01:10 PM, Dave Rolsky wrote: > On Sat, 10 May 2003, Ken Williams wrote: > >> >> On Friday, May 9, 2003, at 05:54 PM, Dave Rolsky wrote: >> >>> On Fri, 9 May 2003, Ken Williams wrote: >>> >>>> I've committed this with a bunch of changes. I put most of the code >>>> into a new Module::Build::PPMMaker module. >>> >>> No, actually you put it in a file called PPD.pm, so it can't find it >>> ;) >> >> Erm, I really did mean to do PPMMaker, but didn't commit the name >> change. Try again now (also a couple other bugs fixed, I think). > > I think it gets too much stuff when looking for the author (try it on > Module::Build to see). A patch to reduce this is below. I think I'm not sure what the Author field is supposed to look like, actually - the http://www.xav.com/perl/site/lib/XML/PPD.html#author and http://search.cpan.org/author/MURRAY/PPM-2.1.6/docs/ppd.pod seem to have different ideas about how to represent the information. -Ken |