[svn:parrot] r39165 - in trunk: . config/gen/makefiles config/init examples/languages/abc/config/makefiles examples/languages/squaak/config/makefiles examples/pir/befunge/config/makefiles ext/SQLite3 lib/Parrot t/tools/install t/tools/install/testlib tools/dev
jkeenan at svn.parrot.org
jkeenan at svn.parrot.org
Mon May 25 01:15:29 UTC 2009
Author: jkeenan
Date: Mon May 25 01:15:28 2009
New Revision: 39165
URL: https://trac.parrot.org/parrot/changeset/39165
Log:
Merge better_install_tools branch into trunk. This branch superseded the install_tools branch but had the same objective: Refactor code found in both tools/dev/install_files.pl and tools/dev/install_dev_files.pl out of those files, place in lib/Parrot/Install.pm, test those subroutines. Cf.: https://trac.parrot.org/parrot/ticket/426. wayland++ for initiating this project and keeping it moving forward.
Added:
trunk/lib/Parrot/Install.pm
- copied unchanged from r39164, branches/better_install_tools/lib/Parrot/Install.pm
trunk/t/tools/install/01-create_directories.t
- copied unchanged from r39164, branches/better_install_tools/t/tools/install/01-create_directories.t
trunk/t/tools/install/02-install_files.t
- copied unchanged from r39164, branches/better_install_tools/t/tools/install/02-install_files.t
trunk/t/tools/install/03-lines_to_files.t
- copied unchanged from r39164, branches/better_install_tools/t/tools/install/03-lines_to_files.t
trunk/t/tools/install/testlib/MANIFEST.1defective
- copied unchanged from r39164, branches/better_install_tools/t/tools/install/testlib/MANIFEST.1defective
trunk/t/tools/install/testlib/README
- copied unchanged from r39164, branches/better_install_tools/t/tools/install/testlib/README
trunk/t/tools/install/testlib/generated_pseudo_with_dupe
- copied unchanged from r39164, branches/better_install_tools/t/tools/install/testlib/generated_pseudo_with_dupe
trunk/t/tools/install/testlib/phony
- copied unchanged from r39164, branches/better_install_tools/t/tools/install/testlib/phony
trunk/t/tools/install/testlib/phony.exe
- copied unchanged from r39164, branches/better_install_tools/t/tools/install/testlib/phony.exe
Modified:
trunk/MANIFEST
trunk/config/gen/makefiles/root.in
trunk/config/init/install.pm
trunk/examples/languages/abc/config/makefiles/root.in
trunk/examples/languages/squaak/config/makefiles/root.in
trunk/examples/pir/befunge/config/makefiles/root.in
trunk/ext/SQLite3/Makefile.in
trunk/t/tools/install/dev_overall.t
trunk/t/tools/install/overall.t
trunk/tools/dev/install_dev_files.pl
trunk/tools/dev/install_files.pl
trunk/tools/dev/mk_language_shell.pl
Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST Mon May 25 00:47:41 2009 (r39164)
+++ trunk/MANIFEST Mon May 25 01:15:28 2009 (r39165)
@@ -1,7 +1,7 @@
# ex: set ro:
# $Id$
#
-# generated by tools/dev/mk_manifest_and_skip.pl Sun May 24 12:35:39 2009 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Sun May 24 16:30:09 2009 UT
#
# See tools/dev/install_files.pl for documentation on the
# format of this file.
@@ -1049,6 +1049,7 @@
lib/Parrot/IO/Directory.pm [devel]lib
lib/Parrot/IO/File.pm [devel]lib
lib/Parrot/IO/Path.pm [devel]lib
+lib/Parrot/Install.pm [devel]lib
lib/Parrot/Manifest.pm [devel]lib
lib/Parrot/Op.pm [devel]lib
lib/Parrot/OpTrans.pm [devel]lib
@@ -2002,9 +2003,14 @@
t/tools/dev/searchops.t [test]
t/tools/dev/searchops/samples.pm [test]
t/tools/dump_pbc.t [test]
+t/tools/install/01-create_directories.t [test]
+t/tools/install/02-install_files.t [test]
+t/tools/install/03-lines_to_files.t [test]
t/tools/install/dev_overall.t [test]
t/tools/install/overall.t [test]
t/tools/install/testlib/LICENSE [test]
+t/tools/install/testlib/MANIFEST.1defective [test]
+t/tools/install/testlib/README []doc
t/tools/install/testlib/compilers/nqp/bootstrap/actions.pm [test]
t/tools/install/testlib/compilers/pge/PGE.pir [test]
t/tools/install/testlib/dev_generated_pseudo [test]
@@ -2014,11 +2020,14 @@
t/tools/install/testlib/docs/pct/past_building_blocks.pod [test]
t/tools/install/testlib/docs/resources/phony_resource [test]
t/tools/install/testlib/generated_pseudo [test]
+t/tools/install/testlib/generated_pseudo_with_dupe [test]
t/tools/install/testlib/include/parrot/charset.h [test]
t/tools/install/testlib/install_config.fpmc [test]
t/tools/install/testlib/lib/Parrot/Configure.pm [test]
t/tools/install/testlib/manifest_pseudo [test]
t/tools/install/testlib/parrot.pc [test]
+t/tools/install/testlib/phony [test]
+t/tools/install/testlib/phony.exe [test]
t/tools/install/testlib/runtime/parrot/include/sockets.pasm [test]
t/tools/install/testlib/runtime/parrot/library/TGE.pbc [test]
t/tools/install/testlib/src/ops/ops.num [test]
Modified: trunk/config/gen/makefiles/root.in
==============================================================================
--- trunk/config/gen/makefiles/root.in Mon May 25 00:47:41 2009 (r39164)
+++ trunk/config/gen/makefiles/root.in Mon May 25 01:15:28 2009 (r39165)
@@ -32,7 +32,7 @@
LIB_DIR := @libdir@
INCLUDE_DIR := @includedir@
DATA_DIR := @datadir@
-DOC_DIR := @doc_dir@
+DOC_DIR := @docdir@
VERSION_DIR = @versiondir@
Modified: trunk/config/init/install.pm
==============================================================================
--- trunk/config/init/install.pm Mon May 25 00:47:41 2009 (r39164)
+++ trunk/config/init/install.pm Mon May 25 01:15:28 2009 (r39165)
@@ -105,7 +105,7 @@
srcdir => $srcdir,
# parrot internal use only
- doc_dir => $datadir . "/doc",
+ docdir => $datadir . "/doc",
versiondir => $versiondir,
);
Modified: trunk/examples/languages/abc/config/makefiles/root.in
==============================================================================
--- trunk/examples/languages/abc/config/makefiles/root.in Mon May 25 00:47:41 2009 (r39164)
+++ trunk/examples/languages/abc/config/makefiles/root.in Mon May 25 01:15:28 2009 (r39165)
@@ -8,7 +8,7 @@
VERSION := @versiondir@
BIN_DIR := @bindir@
LIB_DIR := @libdir@$(VERSION)
-DOC_DIR := @doc_dir@$(VERSION)
+DOC_DIR := @docdir@$(VERSION)
MANDIR := @mandir@$(VERSION)
# Set up extensions
Modified: trunk/examples/languages/squaak/config/makefiles/root.in
==============================================================================
--- trunk/examples/languages/squaak/config/makefiles/root.in Mon May 25 00:47:41 2009 (r39164)
+++ trunk/examples/languages/squaak/config/makefiles/root.in Mon May 25 01:15:28 2009 (r39165)
@@ -8,7 +8,7 @@
VERSION := @versiondir@
BIN_DIR := @bindir@
LIB_DIR := @libdir@$(VERSION)
-DOC_DIR := @doc_dir@$(VERSION)
+DOC_DIR := @docdir@$(VERSION)
MANDIR := @mandir@$(VERSION)
# Set up extensions
Modified: trunk/examples/pir/befunge/config/makefiles/root.in
==============================================================================
--- trunk/examples/pir/befunge/config/makefiles/root.in Mon May 25 00:47:41 2009 (r39164)
+++ trunk/examples/pir/befunge/config/makefiles/root.in Mon May 25 01:15:28 2009 (r39165)
@@ -8,7 +8,7 @@
VERSION := @versiondir@
BIN_DIR := @bindir@
LIB_DIR := @libdir@$(VERSION)
-DOC_DIR := @doc_dir@$(VERSION)
+DOC_DIR := @docdir@$(VERSION)
MANDIR := @mandir@$(VERSION)
# Set up extensions
Modified: trunk/ext/SQLite3/Makefile.in
==============================================================================
--- trunk/ext/SQLite3/Makefile.in Mon May 25 00:47:41 2009 (r39164)
+++ trunk/ext/SQLite3/Makefile.in Mon May 25 01:15:28 2009 (r39165)
@@ -10,10 +10,10 @@
PREFIX = @prefix@
EXEC_PREFIX = @exec_prefix@
DESTDIR =
-BIN_DIR = @bin_dir@
-LIB_DIR = @lib_dir@
-INCLUDE_DIR = @include_dir@
-DOC_DIR = @doc_dir@
+BIN_DIR = @bindir@
+LIB_DIR = @libdir@
+INCLUDE_DIR = @includedir@
+DOC_DIR = @docdir@
INC_DIR = @inc@
RM_F = @rm_f@
RM_RF = @rm_rf@
Copied: trunk/lib/Parrot/Install.pm (from r39164, branches/better_install_tools/lib/Parrot/Install.pm)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/lib/Parrot/Install.pm Mon May 25 01:15:28 2009 (r39165, copy of r39164, branches/better_install_tools/lib/Parrot/Install.pm)
@@ -0,0 +1,239 @@
+package Parrot::Install;
+# Copyright (C) 2001-2009, Parrot Foundation.
+# $Id$
+use strict;
+use warnings;
+use File::Basename qw(dirname);
+use File::Copy;
+use File::Path; # mkpath
+use File::Spec;
+use base qw( Exporter );
+our @EXPORT_OK = qw(
+ lines_to_files
+ create_directories
+ install_files
+);
+
+#################### DOCUMENTATION ####################
+
+=head1 NAME
+
+Parrot::Install - Functionality for installation programs
+
+=head1 SYNOPSIS
+
+ use Parrot::Install qw(
+ install_files
+ create_directories
+ lines_to_files
+ );
+
+=head1 DESCRIPTION
+
+This module exports on demand only three subroutines used in the Parrot
+installation programs F<tools/dev/install_files.pl> and
+F<tools/dev/install_dev_files.pl>. The subroutines are tested by tests found
+in F<t/tools/install/>.
+
+=head1 SUBROUTINES
+
+=head2 C<lines_to_files()>
+
+B<Purpose:> Suck in the lines from the mentioned manifests, and turn them into
+file locations.
+
+B<Arguments:> List of five scalars.
+
+ ($files, $directories) =
+ lines_to_files(
+ \%metatransforms,
+ \@transformorder,
+ \@manifests,
+ \%options,
+ $parrotdir,
+ );
+
+B<Return Value:> List of three scalars.
+
+B<Comment:>
+
+=cut
+
+sub lines_to_files {
+ my ($metatransforms, $transformorder, $manifests_ref,
+ $options_ref, $parrotdir) = @_;
+ my @files;
+ my %directories;
+ my($tkey, $thash);
+ my $filehash;
+
+ # We'll report multiple occurrences of the same file
+ my(%seen);
+
+ # Check $manifests_ref
+ ref($manifests_ref) eq 'ARRAY'
+ or die "Manifests must be listed in an array reference: $!";
+ @{ $manifests_ref } > 0 or die "No manifests specified";
+
+ # Check $transformorder
+ ref($transformorder) eq 'ARRAY'
+ or die "Transform order should be an array of keys\n";
+
+ @ARGV = @{ $manifests_ref };
+ LINE: while ( my $entry = <> ) {
+ chomp $entry;
+
+ $entry =~ s/\#.*//; # Ignore comments
+ next if $entry =~ /^\s*$/; # Skip blank lines
+
+ my ( $src, $meta, $dest ) = split( /\s+/, $entry );
+ $dest = $src unless $dest;
+
+ if ( $seen{$src}++ ) {
+ print STDERR "$ARGV:$.: Duplicate entry $src\n";
+ }
+
+ # Parse out metadata
+ die "Malformed line in MANIFEST: $entry" if not defined $meta;
+ my $generated = $meta =~ s/^\*//;
+ my ($package) = $meta =~ /^\[(.*?)\]/;
+ $meta =~ s/^\[(.*?)\]//;
+ next unless $package; # Skip if this file belongs to no package
+
+ my $plist = defined ( $options_ref->{packages})
+ ? $options_ref->{packages}
+ : '.*';
+ next unless $package =~ /$plist/;
+
+ my %metadata;
+ @metadata{ split( /,/, $meta ) } = ();
+ $metadata{$_} = 1 for ( keys %metadata ); # Laziness
+
+ $filehash = {
+ Source => $src,
+ Dest => $dest,
+ DestDirs => [],
+ };
+
+ FIXFILE: {
+ # Have to catch this case early for some unknown reason
+ if ( $entry =~ /^runtime/ ) {
+ $filehash->{Dest} =~ s/^runtime\/parrot\///;
+ $filehash->{Dest} = File::Spec->catdir(
+ $options_ref->{libdir}, $parrotdir, $filehash->{Dest}
+ );
+ last FIXFILE;
+ }
+ foreach my $tkey (@$transformorder) {
+ $thash = $metatransforms->{$tkey};
+ unless($thash->{ismeta} ? $metadata{$tkey} : $entry =~ /$tkey/) { next; }
+ $filehash = &{ $thash->{transform} }($filehash);
+ ref($filehash) eq 'HASH' or die "Error: transform didn't return a hash for key '$tkey'\n";
+ $filehash->{Dest} = File::Spec->catdir(
+ $options_ref->{$thash->{optiondir} . 'dir'},
+ @{ $filehash->{DestDirs} },
+ $filehash->{Dest}
+ );
+ last FIXFILE;
+ }
+ die "Unknown install location in MANIFEST for file '$entry'\n";
+ }
+
+ if(! $filehash->{Installable}) {
+ $filehash->{Dest} = File::Spec->catdir( $options_ref->{buildprefix}, $filehash->{Dest} )
+ if $options_ref->{buildprefix};
+ }
+
+ $directories{ dirname($filehash->{Dest}) } = 1;
+ push( @files, $filehash );
+ }
+ continue {
+ close ARGV if eof; # Reset line numbering for each input file
+ }
+
+ (grep { ! ref } @files) and die "lines_to_files from Parrot::Install created a bad hash!\n";
+ return(\@files, \%directories);
+}
+
+=head2 C<create_directories()>
+
+B<Purpose:> Creates the directories passed in.
+
+B<Arguments:> Two scalar arguments.
+
+ create_directories(
+ $destination_directory,
+ $directories_hash_ref,
+ );
+
+B<Return Value:> True value.
+
+B<Comment:>
+
+=cut
+
+sub create_directories {
+ my($destdir, $directories) = @_;
+
+ mkpath([
+ grep { ! -d } map { $destdir . $_ } keys %$directories
+ ],0,0777);
+}
+
+=head2 C<install_files()>
+
+B<Purpose:> Install the mentioned files into the appropriate locations.
+
+ install_files(
+ $destination_directory,
+ $dry_run_option,
+ $list_of_files_and_executables,
+ );
+
+B<Arguments:> Takes two scalar arguments, followed by a reference to a
+list consisting of hashes.
+
+B<Return Value:> True value.
+
+B<Comment:>
+
+=cut
+
+sub install_files {
+ my($destdir, $dryrun, $files) = @_;
+ my($src, $dest, $mode);
+
+ ref($files) eq 'ARRAY' or die "Error: parameter \$files must be an array\n";
+ print("Installing ...\n");
+ foreach my $el ( @$files ) {
+ unless(ref($el) eq 'HASH') {
+ my($ref) = ref($el);
+ warn "Bad reference passed in \$files (want a HASH, got a '$ref')\n";
+ next;
+ }
+ ( $src, $dest ) = map { $el->{$_} } qw(Source Dest);
+ $dest = $destdir . $dest;
+ if ( $dryrun ) {
+ print "$src -> $dest\n";
+ next;
+ }
+ else {
+ next unless -e $src;
+ next if $^O eq 'cygwin' and -e "$src.exe"; # stat works, copy not
+ copy( $src, $dest ) or die "Error: couldn't copy $src to $dest: $!\n";
+ print "$dest\n";
+ }
+ $mode = ( stat($src) )[2];
+ chmod $mode, $dest;
+ }
+ return 1;
+}
+
+1;
+
+# Local Variables:
+# mode: cperl
+# cperl-indent-level: 4
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:
Copied: trunk/t/tools/install/01-create_directories.t (from r39164, branches/better_install_tools/t/tools/install/01-create_directories.t)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/t/tools/install/01-create_directories.t Mon May 25 01:15:28 2009 (r39165, copy of r39164, branches/better_install_tools/t/tools/install/01-create_directories.t)
@@ -0,0 +1,101 @@
+#! perl
+# Copyright (C) 2007, Parrot Foundation.
+# $Id$
+# 01-create_directories.t
+
+use strict;
+use warnings;
+
+use Test::More tests => 6;
+use Carp;
+use File::Path qw( mkpath );
+use File::Temp qw( tempdir );
+use lib qw( lib );
+use Parrot::Install qw(
+ create_directories
+);
+use IO::CaptureOutput qw( capture );
+
+{
+ my $tdir = tempdir( CLEANUP => 1 );
+ $tdir .= '/';
+
+ my @dirs = qw(foo/bar foo/bar/baz);
+ create_directories($tdir, { map { $_ => 1 } @dirs });
+ my $dirs_seen = 0;
+ foreach my $d (@dirs) {
+ $dirs_seen++ if -d "$tdir$d";
+ }
+ is($dirs_seen, 2, 'got expected number of directories created');
+}
+
+{
+ my $tdir = tempdir( CLEANUP => 1 );
+ $tdir .= '/';
+
+ my @dirs = qw(foo/bar foo/bar/baz);
+ my @created = mkpath( "$tdir$dirs[0]" );
+ ok( ( -d $created[0] ),
+ "one directory created before create_directories() is called" );
+
+ create_directories($tdir, { map { $_ => 1 } @dirs });
+ my $dirs_seen = 0;
+ foreach my $d (@dirs) {
+ $dirs_seen++ if -d "$tdir$d";
+ }
+ is($dirs_seen, 2,
+ "create_directories() handled case where one directory already existed" );
+}
+
+{
+ my $tdir = tempdir( CLEANUP => 1 );
+ $tdir .= '/';
+
+ my @dirs = qw(foo/bar foo/bar/baz);
+ my @created = mkpath( $tdir . 'foo' );
+ ok( ( -d $created[0] ),
+ "one directory created before create_directories() is called" );
+
+ create_directories($tdir, { map { $_ => 1 } @dirs });
+ my $dirs_seen = 0;
+ foreach my $d (@dirs) {
+ $dirs_seen++ if -d "$tdir$d";
+ }
+ is($dirs_seen, 2,
+ "create_directories() handled case where one path partially existed" );
+}
+
+pass("Completed all tests in $0");
+
+################### DOCUMENTATION ###################
+
+=head1 NAME
+
+01-create_directories.t - test subroutines exported by C<Parrot::Install>
+
+=head1 SYNOPSIS
+
+ % prove t/tools/install/01-create_directories.t
+
+=head1 DESCRIPTION
+
+The files in this directory test functionality used by
+F<tools/dev/install_files.pl> and F<tools/dev/install_dev_files.pl> and
+exported by F<lib/Parrot/Install.pm>.
+
+=head1 AUTHOR
+
+James E Keenan and Timothy S Nelson
+
+=head1 SEE ALSO
+
+Parrot::Install, F<tools/dev/install_files.pl>, F<tools/dev/install_dev_files.pl>
+
+=cut
+
+# Local Variables:
+# mode: cperl
+# cperl-indent-level: 4
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:
Copied: trunk/t/tools/install/02-install_files.t (from r39164, branches/better_install_tools/t/tools/install/02-install_files.t)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/t/tools/install/02-install_files.t Mon May 25 01:15:28 2009 (r39165, copy of r39164, branches/better_install_tools/t/tools/install/02-install_files.t)
@@ -0,0 +1,283 @@
+#! perl
+# Copyright (C) 2007, Parrot Foundation.
+# $Id$
+# 02-install_files.t
+
+use strict;
+use warnings;
+
+use Test::More tests => 18;
+use Carp;
+use Cwd;
+use File::Copy;
+use File::Path qw( mkpath );
+use File::Temp qw( tempdir );
+use lib qw( lib );
+use Parrot::Install qw(
+ install_files
+ create_directories
+);
+use IO::CaptureOutput qw( capture );
+
+my $cwd = cwd();
+my $testsourcedir = qq{$cwd/t/tools/install/testlib};
+
+{
+ my $tdir = tempdir( CLEANUP => 1 );
+ $tdir .= '/';
+
+ my @dirs = qw(foo/bar foo/bar/baz);
+ create_directories($tdir, { map { $_ => 1 } @dirs });
+
+ {
+ my ( $stdout, $stderr, $rv );
+
+ eval {
+ capture(
+ sub { $rv = install_files($tdir, 1); },
+ \$stdout,
+ \$stderr,
+ );
+ };
+ like($@, qr/Error: parameter \$files must be an array/s, "Catches non-ARRAY \$files");
+ }
+}
+
+{
+ my $tdir = tempdir( CLEANUP => 1 );
+ $tdir .= '/';
+
+ my @dirs = qw(foo/bar foo/bar/baz);
+ create_directories($tdir, { map { $_ => 1 } @dirs });
+
+ # Case where element in @files is not a hash ref
+ my $files_ref = [ q[] ];
+
+ {
+ my ( $stdout, $stderr, $rv );
+ capture(
+ sub { $rv = install_files($tdir, 0, $files_ref); },
+ \$stdout,
+ \$stderr,
+ );
+ like($stderr, qr/Bad reference passed in \$files/, "Catches non-HASH files");
+
+ like( $stdout, qr/Installing \.\.\./,
+ 'Got expected installation message' );
+ }
+}
+
+{
+ my $tdir = tempdir( CLEANUP => 1 );
+ $tdir .= '/';
+
+ my @dirs = qw(foo/bar foo/bar/baz);
+ create_directories($tdir, { map { $_ => 1 } @dirs });
+
+ my $files_ref = [ {
+ Source => "$testsourcedir/README",
+ Dest => "$dirs[0]/README",
+ } ];
+
+ {
+ my ( $stdout, $stderr, $rv );
+
+ capture(
+ sub { $rv = install_files($tdir, 1, $files_ref); },
+ \$stdout,
+ \$stderr,
+ );
+ ok( $rv, 'install_files() completed successfully in dry-run case' );
+
+ my $files_created = 0;
+ foreach my $el (@$files_ref) {
+ $files_created++ if -f $tdir . $el->{Dest};
+ }
+ is( $files_created, 0, 'Dry run, so no files created' );
+
+ like( $stdout, qr/Installing.*README.*README/s,
+ 'Got expected installation message' );
+ $stdout =~ qr/Installing.*README.*README/s or print "Warning was: $stderr";
+ }
+
+ {
+ my ( $stdout, $stderr, $rv );
+ capture(
+ sub { $rv = install_files($tdir, 0, $files_ref); },
+ \$stdout,
+ \$stderr,
+ );
+ ok( $rv, 'install_files() completed successfully in production case' );
+
+ my $files_created = 0;
+ foreach my $el (@$files_ref) {
+ $files_created++ if -f "$tdir$el->{Dest}";
+ }
+ is( $files_created, 1, 'Production, so 1 file created' );
+
+ like( $stdout, qr/Installing.*README/s,
+ 'Got expected installation message' );
+ }
+}
+
+{
+ local $^O = 'cygwin';
+ my $tdir = tempdir( CLEANUP => 1 );
+ chdir $tdir or die "Unable to change to testing directory: $!";
+ $tdir .= '/';
+
+ my @dirs = qw(foo/bar foo/bar/baz);
+ create_directories($tdir, { map { $_ => 1 } @dirs });
+
+ my @testingfiles = qw( README phony );
+ foreach my $f ( @testingfiles ) {
+ copy "$testsourcedir/$f", "$tdir/$f"
+ or die "Unable to copy $f prior to testing: $!";
+ }
+ my $files_ref = [
+ {
+ Source => "$tdir/README",
+ Dest => "$dirs[0]/README",
+ },
+ {
+ Source => "$tdir/phony",
+ Dest => "$dirs[0]/phony",
+ },
+ ];
+
+ {
+ my ( $stdout, $stderr, $rv );
+ capture(
+ sub { $rv = install_files($tdir, 0, $files_ref); },
+ \$stdout,
+ \$stderr,
+ );
+ ok( $rv, 'install_files() completed successfully in mock-Cygwin case' );
+
+ my $files_created = 0;
+ foreach my $el (@$files_ref) {
+ $files_created++ if -f "$tdir$el->{Dest}";
+ }
+ is( $files_created, 2, 'Production, so 2 files created' );
+
+ like( $stdout, qr/Installing.*README.*phony/s,
+ 'Got expected installation message' );
+ }
+ chdir $cwd or die "Unable to change back to starting directory: $!";
+}
+
+{
+ local $^O = 'cygwin';
+ my $tdir = tempdir( CLEANUP => 1 );
+ chdir $tdir or die "Unable to change to testing directory: $!";
+ $tdir .= '/';
+
+ my @dirs = qw(foo/bar foo/bar/baz);
+ create_directories($tdir, { map { $_ => 1 } @dirs });
+
+ my @testingfiles = qw( README phony phony.exe );
+ foreach my $f ( @testingfiles ) {
+ copy "$testsourcedir/$f", "$tdir/$f"
+ or die "Unable to copy $f prior to testing: $!";
+ }
+ my $files_ref = [
+ {
+ Source => "$tdir/README",
+ Dest => "$dirs[0]/README"
+ },
+ {
+ Source => "$tdir/phony",
+ Dest => "$dirs[0]/phony"
+ },
+ {
+ Source => "$tdir/phony.exe",
+ Dest => "$dirs[0]/phony.exe"
+ },
+ ];
+
+ {
+ my ( $stdout, $stderr, $rv );
+ capture(
+ sub { $rv = install_files($tdir, 0, $files_ref); },
+ \$stdout,
+ \$stderr,
+ );
+ ok( $rv, 'install_files() completed successfully in mock-Cygwin case' );
+
+ my $files_created = 0;
+ foreach my $el (@$files_ref) {
+ $files_created++ if -f "$tdir$el->{Dest}";
+ }
+ is( $files_created, 2,
+ 'Production, so 2 files created; 1 file passed over' );
+
+ like( $stdout, qr/Installing.*README.*phony/s,
+ 'Got expected installation message' );
+ }
+ chdir $cwd or die "Unable to change back to starting directory: $!";
+}
+
+{
+ my $tdir = tempdir( CLEANUP => 1 );
+ $tdir .= '/';
+
+ my @dirs = qw(foo/bar foo/bar/baz);
+ create_directories($tdir, { map { $_ => 1 } @dirs });
+
+ # Case where element in @files does not hold existent file
+ my $nonexistent = q{ajdpfadksjfjvjkvds} . $$;
+ my $files_ref = [
+ {
+ Source => $nonexistent,
+ Dest => "$dirs[0]/$nonexistent",
+ }
+ ];
+
+ {
+ my ( $stdout, $stderr, $rv );
+ capture(
+ sub { $rv = install_files($tdir, 0, $files_ref); },
+ \$stdout,
+ \$stderr,
+ );
+ ok( $rv, 'install_files() handled non-existent file as expected' );
+
+ like( $stdout, qr/Installing \.\.\./,
+ 'Got expected installation message' );
+ }
+}
+
+pass("Completed all tests in $0");
+
+################### DOCUMENTATION ###################
+
+=head1 NAME
+
+02-install_files.t - test subroutines exported by C<Parrot::Install>
+
+=head1 SYNOPSIS
+
+ % prove t/tools/install/02-install_files.t
+
+=head1 DESCRIPTION
+
+The files in this directory test functionality used by
+F<tools/dev/install_files.pl> and F<tools/dev/install_dev_files.pl> and
+exported by F<lib/Parrot/Install.pm>.
+
+=head1 AUTHOR
+
+James E Keenan and Timothy S Nelson
+
+=head1 SEE ALSO
+
+Parrot::Install, F<tools/dev/install_files.pl>, F<tools/dev/install_dev_files.pl>
+
+=cut
+
+# Local Variables:
+# mode: cperl
+# cperl-indent-level: 4
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:
Copied: trunk/t/tools/install/03-lines_to_files.t (from r39164, branches/better_install_tools/t/tools/install/03-lines_to_files.t)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/t/tools/install/03-lines_to_files.t Mon May 25 01:15:28 2009 (r39165, copy of r39164, branches/better_install_tools/t/tools/install/03-lines_to_files.t)
@@ -0,0 +1,292 @@
+#! perl
+# Copyright (C) 2007, Parrot Foundation.
+# $Id$
+# 03-lines_to_files.t
+
+use strict;
+use warnings;
+
+use Test::More tests => 8;
+use Carp;
+use Cwd;
+use File::Copy;
+use File::Path qw( mkpath );
+use File::Temp qw( tempdir );
+use lib qw( lib );
+use Parrot::Install qw(
+ install_files
+ create_directories
+ lines_to_files
+);
+use IO::CaptureOutput qw( capture );
+
+my $cwd = cwd();
+my $testsourcedir = qq{$cwd/t/tools/install/testlib};
+
+my $parrotdir = q{};
+
+my %metatransforms = (
+ doc => {
+ optiondir => 'doc',
+ transform => sub {
+ my($dest) = @_;
+ # resources go in the top level of docs
+ $dest =~ s/^docs\/resources/resources/;
+ # other docs are actually raw Pod
+ $dest =~ s/^docs/pod/;
+ $parrotdir, $dest;
+ },
+ },
+ '.*' => {
+ optiondir => 'foo',
+ transform => sub {
+ return($_[0]);
+ }
+ }
+);
+my(@transformorder) = ('doc', '.*');
+
+my %badmetatransforms = (
+ doc => {
+ optiondir => 'doc',
+ transform => sub {
+ my($dest) = @_;
+ $dest =~ s/^docs\/resources/resources/; # resources go in the top level of docs
+ $dest =~ s/^docs/pod/; # other docs are actually raw Pod
+ $parrotdir, $dest;
+ },
+ },
+ '.*' => {
+ optiondir => 'foo',
+ transform => sub {
+ return(@_);
+ }
+ }
+);
+
+my @manifests = qw(MANIFEST MANIFEST.generated);
+my %options = (
+ packages => 'main',
+);
+
+my ($files_ref, $directories_ref, %badtransformorder);
+
+eval {
+ ($files_ref, $directories_ref) =
+ lines_to_files(
+ \%metatransforms,
+ \@transformorder,
+ {},
+ \%options,
+ $parrotdir,
+ );
+};
+like($@, qr/Manifests must be listed in an array reference/,
+ "Correctly detected lack of array ref as 3rd argument"
+);
+
+eval {
+ ($files_ref, $directories_ref) =
+ lines_to_files(
+ \%metatransforms,
+ \@transformorder,
+ [],
+ \%options,
+ $parrotdir,
+ );
+};
+like($@, qr/No manifests specified/,
+ "Correctly detected lack of manifest files"
+);
+
+eval {
+ ($files_ref, $directories_ref) =
+ lines_to_files(
+ \%metatransforms,
+ \%badtransformorder,
+ [ qw( MANIFEST MANIFEST.generated ) ],
+ \%options,
+ $parrotdir,
+ );
+};
+like($@, qr/Transform order should be an array of keys/,
+ "Correctly detected incorrect type for transform order"
+);
+
+{
+ my $tdir = tempdir( CLEANUP => 1 );
+ chdir $tdir or die "Unable to change to testing directory: $!";
+ copy qq{$testsourcedir/manifest_pseudo} => qq{$tdir/MANIFEST}
+ or die "Unable to copy file to tempdir for testing: $!";
+ copy qq{$testsourcedir/generated_pseudo} => qq{$tdir/MANIFEST.generated}
+ or die "Unable to copy file to tempdir for testing: $!";
+
+ my ($stdout, $stderr);
+ eval {
+ ($files_ref, $directories_ref) =
+ lines_to_files(
+ \%badmetatransforms,
+ \@transformorder,
+ [ qw( MANIFEST MANIFEST.generated ) ],
+ \%options,
+ $parrotdir,
+ );
+ };
+ like($@, qr/transform didn't return a hash for key/,
+ "Correctly detected transform with a bad return value"
+ );
+
+ chdir $cwd or die "Unable to return to starting directory: $!";
+}
+
+{
+ my $tdir = tempdir( CLEANUP => 1 );
+ chdir $tdir or die "Unable to change to testing directory: $!";
+ copy qq{$testsourcedir/manifest_pseudo} => qq{$tdir/MANIFEST}
+ or die "Unable to copy file to tempdir for testing: $!";
+ copy qq{$testsourcedir/generated_pseudo_with_dupe} => qq{$tdir/MANIFEST.generated}
+ or die "Unable to copy file to tempdir for testing: $!";
+
+ my ($stdout, $stderr);
+ eval {
+ capture(
+ sub {
+ ($files_ref, $directories_ref) =
+ lines_to_files(
+ \%metatransforms,
+ \@transformorder,
+ [ qw( MANIFEST MANIFEST.generated ) ],
+ \%options,
+ $parrotdir,
+ );
+ },
+ \$stdout,
+ \$stderr,
+ );
+ };
+ like($stderr, qr/MANIFEST\.generated:\d+:\s+Duplicate entry/,
+ "Detected duplicate entries in one or more manifest files" );
+ is( scalar(grep { $_->{Installable} } @$files_ref), 0,
+ "No installable executables in this test" );
+
+ chdir $cwd or die "Unable to return to starting directory: $!";
+}
+
+{
+ my $tdir = tempdir( CLEANUP => 1 );
+ chdir $tdir or die "Unable to change to testing directory: $!";
+ my $defective_man = q{MANIFEST.1defective};
+ copy qq{$testsourcedir/$defective_man} => qq{$tdir/MANIFEST}
+ or die "Unable to copy file to tempdir for testing: $!";
+
+ eval {
+ ($files_ref, $directories_ref) =
+ lines_to_files(
+ \%metatransforms,
+ \@transformorder,
+ [ q{MANIFEST} ],
+ \%options,
+ $parrotdir,
+ );
+ };
+ like($@, qr/Malformed line in MANIFEST: ChangeLog/,
+ "Got expected error message with defective manifest" );
+
+ chdir $cwd or die "Unable to return to starting directory: $!";
+}
+
+
+pass("Completed all tests in $0");
+
+################### DOCUMENTATION ###################
+
+=head1 NAME
+
+03-lines_to_files.t - test subroutines exported by C<Parrot::Install>
+
+=head1 SYNOPSIS
+
+ % prove t/tools/install/03-lines_to_files.t
+
+=head1 DESCRIPTION
+
+The files in this directory test functionality used by
+F<tools/dev/install_files.pl> and F<tools/dev/install_dev_files.pl> and
+exported by F<lib/Parrot/Install.pm>.
+
+=head1 AUTHOR
+
+James E Keenan and Timothy S Nelson
+
+=head1 SEE ALSO
+
+Parrot::Install, F<tools/dev/install_files.pl>, F<tools/dev/install_dev_files.pl>
+
+=cut
+
+# Local Variables:
+# mode: cperl
+# cperl-indent-level: 4
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:
+
+__END__
+
+# Can't safely run lines_to_files() more than once in a program until it's been fixed,
+# and we can't fix it until its tested, so I've commented most of these out until we've
+# fixed lines_to_files() not to use @ARGV
+
+
+
+## In the code below:
+## - othertransforms needs to be merged into metatransforms
+## - transformorder needs to be added
+## - $installable_exe needs to be removed
+
+#{
+# my($metatransforms, $transformorder, $manifests, $options, $parrotdir,
+# $files, $installable_exe, $directories);
+#
+# # First lines_to_files test
+## eval { lines_to_files(); };
+## $@ or die "lines_to_files didn't die with no parameters\n";
+## ok($@ =~ /^.manifests must be an array reference$/, 'lines_to_files dies with bad parameters');
+#
+# # Second lines_to_files test
+## eval { lines_to_files(
+## $metatransforms, $transformorder,
+## [qw(MANIFEST MANIFEST.generated)],
+## $options, $parrotdir
+## ); };
+## ok($@ =~ /^Unknown install location in MANIFEST for file/, 'fails for install locations not specified in transforms');
+#
+# # Third lines_to_files test
+# $metatransforms = {
+# doc => {
+# optiondir => 'doc',
+# transform => sub {
+# my($dest) = @_;
+# $dest =~ s/^docs\/resources/resources/; # resources go in the top level of docs
+# $dest =~ s/^docs/pod/; # other docs are actually raw Pod
+# $parrotdir, $dest;
+# },
+# },
+# };
+# $othertransforms = {
+# '.*' => {
+# optiondir => 'foo',
+# transform => sub {
+# return(@_);
+# }
+# }
+# };
+#
+# ($files, $installable_exe, $directories) = lines_to_files(
+# $metatransforms, $othertransforms,
+# [qw(MANIFEST MANIFEST.generated)],
+# { packages => 'main' }, $parrotdir
+# );
+# ok((ref($files) and ref($installable_exe) and ref($directories)), 'lines_to_files returns something vaguely sensible');
+# ok(1, 'lines_to_files passed all tests');
+#}
Modified: trunk/t/tools/install/dev_overall.t
==============================================================================
--- trunk/t/tools/install/dev_overall.t Mon May 25 00:47:41 2009 (r39164)
+++ trunk/t/tools/install/dev_overall.t Mon May 25 01:15:28 2009 (r39165)
@@ -123,7 +123,8 @@
my $des = File::Spec->catfile( $builddir, $testfiles{$f}{start} );
copy $src, $des or croak "Unable to copy $f for testing: $!";
}
- my $cmd = qq{$^X $full_installer --prefix=$prefixdir};
+ my $addlib = qq{$cwd/lib};
+ my $cmd = qq{$^X -I$addlib $full_installer --prefix=$prefixdir};
$cmd .= qq{ --includedir=$includedir};
$cmd .= qq{ --libdir=$libdir};
$cmd .= qq{ --versiondir=$versiondir};
Modified: trunk/t/tools/install/overall.t
==============================================================================
--- trunk/t/tools/install/overall.t Mon May 25 00:47:41 2009 (r39164)
+++ trunk/t/tools/install/overall.t Mon May 25 01:15:28 2009 (r39165)
@@ -15,6 +15,11 @@
use File::Temp qw( tempdir );
use lib qw( lib );
use Parrot::Config qw( %PConfig );
+use Parrot::Install qw(
+ install_files
+ create_directories
+ lines_to_files
+);
use IO::CaptureOutput qw( capture );
my $DEBUG = 0;
@@ -108,7 +113,8 @@
my $des = File::Spec->catfile( $builddir, $testfiles{$f}{start} );
copy $src, $des or croak "Unable to copy $f for testing: $!";
}
- my $cmd = qq{$^X $full_installer --prefix=$prefixdir};
+ my $addlib = qq{$cwd/lib};
+ my $cmd = qq{$^X -I$addlib $full_installer --prefix=$prefixdir};
$cmd .= qq{ --includedir=$includedir};
$cmd .= qq{ --libdir=$libdir};
$cmd .= qq{ --versiondir=$versiondir};
@@ -131,7 +137,6 @@
my $expected = scalar keys %testfiles;
foreach my $f ( keys %testfiles ) {
my $des = $testfiles{$f}{end};
- print STDERR "wanted: $des\n" if $DEBUG;
$seen++ if -f $des;
}
is( $seen, $expected,
Copied: trunk/t/tools/install/testlib/MANIFEST.1defective (from r39164, branches/better_install_tools/t/tools/install/testlib/MANIFEST.1defective)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/t/tools/install/testlib/MANIFEST.1defective Mon May 25 01:15:28 2009 (r39165, copy of r39164, branches/better_install_tools/t/tools/install/testlib/MANIFEST.1defective)
@@ -0,0 +1,5 @@
+# $Id$
+#
+# generated by hand for testing purposes only
+CREDITS [] /destination/to/file
+ChangeLog
Copied: trunk/t/tools/install/testlib/README (from r39164, branches/better_install_tools/t/tools/install/testlib/README)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/t/tools/install/testlib/README Mon May 25 01:15:28 2009 (r39165, copy of r39164, branches/better_install_tools/t/tools/install/testlib/README)
@@ -0,0 +1,155 @@
+This is Parrot, version 0.9.1
+------------------------------
+
+Parrot is Copyright (C) 2001-2009, Parrot Foundation.
+
+$Id$
+
+LICENSE INFORMATION
+-------------------
+
+This code is distributed under the terms of the Artistic License 2.0.
+For more details, see the full text of the license in the file LICENSE.
+
+PREREQUISITES
+-------------
+
+You need a C compiler, a linker, and a make program of course. If you will be
+linking with the ICU library you have to download and install it before
+configuring Parrot.
+
+Get it from http://www-306.ibm.com/software/globalization/icu/downloads.jsp
+
+You also need Perl 5.8.4 or newer, Storable 2.12 or newer, and Bundle::Parrot
+to run various configure and build scripts.
+
+For most of the platforms that we are supporting initially, Parrot should build
+out of the box. PLATFORM lists our target platforms.
+
+The current configure system is primitive, as it's only a temporary solution.
+It will be happy with most any answers you decide to feed it. Garbage In,
+Garbage Out.
+
+INSTRUCTIONS
+------------
+
+For now, unpack your Parrot tarball, (if you're reading this, you've
+probably already done that) and type
+
+ perl Configure.pl
+
+to run the Configure script. The Configure.pl script extracts
+configuration from the running perl5 program. Unfortunately, the perl5
+configuration is not set up to compile and link c++ programs, so you
+may need to explicitly tell Configure.pl which compiler and linker to
+use. For example, to compile C files with 'cc', C++ files with
+'CC', and link everything together with 'CC', you would type
+
+ perl Configure.pl --cc=cc --cxx=CC --link=CC --ld=CC
+
+See "perl Configure.pl --help" for more options and docs/configuration.pod
+for more details.
+
+For systems like HPUX that don't have inet_pton please run
+
+ perl Configure.pl --define=inet_aton
+
+Running Configure.pl will generate a config.h header, a Parrot::Config
+module, platform files and many Makefiles.
+
+The file "myconfig" has an overview of configure settings.
+
+Next, run make. (Configure.pl will tell you which version of make it
+recommends for your system.)
+
+Now, the interpreter should build. If you are building the ICU library
+(this is the default on most systems), you need to use GNU make instead
+(or something compatible with it).
+
+NOTE: If you have trouble linking parrot, this *may* be due to a pre-existing
+parrot version installed via 'make install'. Until this issue is resolved,
+you may have to delete the installed version of parrot before building a new
+one. Our apologies.
+
+You can test parrot by running "make test". You can run the tests in parallel
+with "make TEST_JOBS=3 test".
+
+You can run the full test suite with
+
+ make fulltest
+
+Note: PLATFORMS contains notes about whether test failures are expected
+on your system.
+
+On some systems you can install parrot:
+
+ make install
+
+This installs a bunch of files in /usr/local. The parrot executable is in
+/usr/local/bin. Please note that this feature is currently experimental.
+(It's so experimental that you have to read the directions it gives you.)
+
+If you want to install Parrot into a non-standard location use:
+
+ perl Configure.pl --prefix=/Users/foo/parrot-0.7.0
+ make install
+
+But please note that dynamic libs will not be found for non-standard
+locations unless you set LD_LIBRARY_PATH or similar.
+
+Look at docs/parrot.pod and docs/intro.pod for where to go from here. If you
+have any problems, see the section "How To Submit A Bug Report" in
+docs/submissions.pod. These documents are in POD format. You can view these
+files with the command:
+
+ perldoc -F docs/intro.pod
+
+NOTES
+-----
+
+On some older computers with little RAM, the computed-goto dispatch core
+(ops/core_ops_cg.c) may take a while to compile or may fail to compile at all.
+You can pass a flag to Configure.pl (--cgoto=0) to disable the computed-goto
+core, at a slight cost in runtime speed.
+
+CHANGES
+-------
+
+For documentation on the user-visible changes between this version and
+previous versions, please see NEWS.
+
+MAILING LISTS
+-------------
+
+The mailing list for parrot is parrot-dev at lists.parrot.org. Subscribe by
+filling out the form at http://lists.parrot.org/mailman/listinfo/parrot-dev
+It is archived at http://lists.parrot.org/pipermail/parrot-dev/
+
+The old development list is archived at
+http://www.nntp.perl.org/group/perl.perl6.internals
+and available via NNTP at nntp://nntp.perl.org/perl.perl6.internals
+
+You can also read the (old) list via Google Groups at
+http://groups-beta.google.com/group/perl.perl6.internals
+
+FEEDBACK, PATCHES, etc.
+-----------------------
+
+See F<docs/submissions.pod> for more information on reporting bugs and
+submitting patches.
+
+WEB SITES
+---------
+
+The following web sites have all the information you need about Parrot:
+ http://www.parrot.org/
+ http://trac.parrot.org/
+ http://www.parrotblog.org/
+
+And Perl6:
+ http://rakudo.org/
+ http://dev.perl.org/perl6/
+ http://pugscode.org/
+
+Have fun,
+ The Parrot Team.
Copied: trunk/t/tools/install/testlib/generated_pseudo_with_dupe (from r39164, branches/better_install_tools/t/tools/install/testlib/generated_pseudo_with_dupe)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/t/tools/install/testlib/generated_pseudo_with_dupe Mon May 25 01:15:28 2009 (r39165, copy of r39164, branches/better_install_tools/t/tools/install/testlib/generated_pseudo_with_dupe)
@@ -0,0 +1,10 @@
+# $Id$
+# See tools/dev/install_files.pl for documentation on the
+# format of this file.
+# Please re-sort this file after *EVERY* modification
+install_config.fpmc [main]lib
+parrot.pc [main]pkgconfig
+parrot.pc [main]pkgconfig
+# Local variables:
+# mode: text
+# End:
Copied: trunk/t/tools/install/testlib/phony (from r39164, branches/better_install_tools/t/tools/install/testlib/phony)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/t/tools/install/testlib/phony Mon May 25 01:15:28 2009 (r39165, copy of r39164, branches/better_install_tools/t/tools/install/testlib/phony)
@@ -0,0 +1 @@
+File used in testing of Parrot::Install.
Copied: trunk/t/tools/install/testlib/phony.exe (from r39164, branches/better_install_tools/t/tools/install/testlib/phony.exe)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/t/tools/install/testlib/phony.exe Mon May 25 01:15:28 2009 (r39165, copy of r39164, branches/better_install_tools/t/tools/install/testlib/phony.exe)
@@ -0,0 +1 @@
+File used in testing of Parrot::Install; not a real executable.
Modified: trunk/tools/dev/install_dev_files.pl
==============================================================================
--- trunk/tools/dev/install_dev_files.pl Mon May 25 00:47:41 2009 (r39164)
+++ trunk/tools/dev/install_dev_files.pl Mon May 25 01:15:28 2009 (r39165)
@@ -57,9 +57,13 @@
use strict;
use warnings;
-use File::Basename qw(dirname basename);
-use File::Copy;
-use File::Spec;
+use File::Basename qw(basename);
+use lib qw( lib );
+use Parrot::Install qw(
+ install_files
+ create_directories
+ lines_to_files
+);
# When run from the makefile, which is probably the only time this
# script will ever be used, all of these defaults will get overridden.
@@ -74,7 +78,9 @@
docdir => '/usr/share/doc', # parrot/ subdir added below
datadir => '/usr/share/', # parrot/ subdir added below
srcdir => '/usr/src/', # parrot/ subdir added below
+ versiondir => '',
'dry-run' => 0,
+ packages => 'devel|pct|tge|nqp',
);
my @manifests;
@@ -89,118 +95,88 @@
my $parrotdir = $options{versiondir};
-# We'll report multiple occurrences of the same file
-my %seen;
-
-my @files;
-my @installable_exe;
-my %directories;
- at ARGV = @manifests;
-while (<>) {
- chomp;
-
- s/\#.*//; # Ignore comments
- next if /^\s*$/; # Skip blank lines
-
- my ( $src, $meta, $dest ) = split( /\s+/, $_ );
- $dest ||= $src;
-
- if ( $seen{$src}++ ) {
- print STDERR "$ARGV:$.: Duplicate entry $src\n";
- }
-
- # Parse out metadata
- die "Malformed line in MANIFEST: $_" if not defined $meta;
- my $generated = $meta =~ s/^\*//;
- my ($package) = $meta =~ /^\[(.*?)\]/;
- $meta =~ s/^\[(.*?)\]//;
- next unless $package; # Skip if this file belongs to no package
-
- next unless $package =~ /devel|pct|tge|nqp/;
-
- my %meta;
- @meta{ split( /,/, $meta ) } = ();
- $meta{$_} = 1 for ( keys %meta ); # Laziness
-
- if ( $meta{lib} ) {
- $dest = File::Spec->catdir( $options{libdir}, $parrotdir, "tools", $dest );
- }
- elsif ( $meta{share} ) {
- $dest = File::Spec->catdir( $options{datadir}, $parrotdir, basename($dest) );
- }
- elsif ( $meta{include} ) {
- $dest =~ s/^src//; # strip off leading src/ dir
- $dest =~ s/^include//;
- $dest = File::Spec->catdir( $options{includedir}, $parrotdir, $dest );
- }
- elsif ( $meta{src} ) {
- $dest =~ s/^src//; # strip off leading src/ dir
- $dest = File::Spec->catdir( $options{srcdir}, $parrotdir, $dest );
- }
- elsif ( $meta{doc} ) {
- $dest =~ s/^docs/pod/; # docs dir are actually raw Pod
- $dest = File::Spec->catdir( $options{docdir}, $parrotdir, $dest );
- }
- elsif ( /^runtime/ ) {
- $dest =~ s/^runtime\/parrot\///;
- $dest = File::Spec->catdir( $options{libdir}, $parrotdir, $dest );
- }
- elsif ( /^tools/ ) {
- $dest = File::Spec->catdir( $options{libdir}, $parrotdir, $dest );
- }
- elsif ( /^VERSION/ ) {
- $dest = File::Spec->catdir( $options{libdir}, $parrotdir, $dest );
- }
- elsif ( /^compilers/ ) {
- $dest =~ s/^compilers/languages/;
- $dest = File::Spec->catdir( $options{libdir}, $parrotdir, $dest );
- }
- else {
- die "Unknown file type in MANIFEST: $_";
- }
-
- $dest = File::Spec->catdir( $options{buildprefix}, $dest )
- if $options{buildprefix};
+# Set up transforms on filenames
+my(@transformorder) = (qw(lib share include src doc), '^(tools|VERSION)', '^compilers');
+my(%metatransforms) = (
+ lib => {
+ ismeta => 1,
+ optiondir => 'lib',
+ transform => sub {
+ my($filehash) = @_;
+ $filehash->{DestDirs} = [$parrotdir, "tools"];
+ return($filehash);
+ },
+ },
+ share => {
+ ismeta => 1,
+ optiondir => 'data',
+ transform => sub {
+ my($filehash) = @_;
+ $filehash->{Dest} = basename($filehash->{Dest});
+ $filehash->{DestDirs} = [$parrotdir];
+ return($filehash);
+ },
+ },
+ include => {
+ ismeta => 1,
+ optiondir => 'include',
+ transform => sub {
+ my($filehash) = @_;
+ $filehash->{Dest} =~ s/^src//; # strip off leading src/ dir
+ $filehash->{Dest} =~ s/^include//;
+ $filehash->{DestDirs} = [$parrotdir];
+ return($filehash);
+ },
+ },
+ src => {
+ ismeta => 1,
+ optiondir => 'src',
+ transform => sub {
+ my($filehash) = @_;
+ $filehash->{Dest} =~ s/^src//; # strip off leading src/ dir
+ $filehash->{DestDirs} = [$parrotdir];
+ return($filehash);
+ },
+ },
+ doc => {
+ ismeta => 1,
+ optiondir => 'doc',
+ transform => sub {
+ my($filehash) = @_;
+ $filehash->{Dest} =~ s/^docs/pod/; # other docs are actually raw Pod
+ $filehash->{DestDirs} = [$parrotdir];
+ return($filehash);
+ },
+ },
+ '^(tools|VERSION)' => {
+ optiondir => 'lib',
+ transform => sub {
+ my($filehash) = @_;
+ $filehash->{DestDirs} = [$parrotdir];
+ return($filehash);
+ },
+ },
+ '^compilers' => {
+ optiondir => 'lib',
+ transform => sub {
+ my($filehash) = @_;
+ $filehash->{Dest} =~ s/^compilers/languages/;
+ $filehash->{DestDirs} = [$parrotdir];
+ return($filehash);
+ },
+ },
+);
- $directories{ dirname($dest) } = 1;
- push( @files, [ $src => $dest ] );
-}
-continue {
- close ARGV if eof; # Reset line numbering for each input file
-}
+my($filehashes, $directories) = lines_to_files(
+ \%metatransforms, \@transformorder, \@manifests, \%options, $parrotdir
+);
unless ( $options{'dry-run'} ) {
- for my $dir ( map { $options{destdir} . $_ } keys %directories ) {
- unless ( -d $dir ) {
-
- # Make full path to the directory $dir
- my @dirs;
- while ( !-d $dir ) { # Scan up to nearest existing ancestor
- unshift @dirs, $dir;
- $dir = dirname($dir);
- }
- foreach (@dirs) {
- mkdir( $_, 0777 ) or die "mkdir $_: $!\n";
- }
- }
- }
-}
-print("Installing ...\n");
-foreach ( @files, @installable_exe ) {
- my ( $src, $dest ) = @$_;
- $dest = $options{destdir} . $dest;
- if ( $options{'dry-run'} ) {
- print "$src -> $dest\n";
- next;
- }
- else {
- next unless -e $src;
- copy( $src, $dest ) or die "copy $src to $dest: $!\n";
- print "$dest\n";
- }
- my $mode = ( stat($src) )[2];
- chmod $mode, $dest;
+ create_directories($options{destdir}, $directories);
}
+install_files($options{destdir}, $options{'dry-run'}, $filehashes);
+
+print "Finished install_dev_files.pl\n";
# Local Variables:
# mode: cperl
Modified: trunk/tools/dev/install_files.pl
==============================================================================
--- trunk/tools/dev/install_files.pl Mon May 25 00:47:41 2009 (r39164)
+++ trunk/tools/dev/install_files.pl Mon May 25 01:15:28 2009 (r39165)
@@ -1,199 +1,9 @@
#! perl
################################################################################
-# Copyright (C) 2001-2008, Parrot Foundation.
+# Copyright (C) 2001-2009, Parrot Foundation.
# $Id$
################################################################################
-use strict;
-use warnings;
-use File::Basename qw(dirname basename);
-use File::Copy;
-use File::Spec;
-
-# When run from the makefile, which is probably the only time this
-# script will ever be used, all of these defaults will get overridden.
-my %options = (
- buildprefix => '',
- prefix => '/usr',
- destdir => '',
- exec_prefix => '/usr',
- bindir => '/usr/bin',
- libdir => '/usr/lib', # parrot/ subdir added below
- includedir => '/usr/include', # parrot/ subdir added below
- docdir => '/usr/share/doc', # parrot/ subdir added below
- version => '',
- 'dry-run' => 0,
-);
-
-my @manifests;
-foreach my $arg (@ARGV) {
- if ( $arg =~ m/^--([^=]+)=(.*)/ ) {
- $options{$1} = $2;
- }
- else {
- push @manifests, $arg;
- }
-}
-
-my $parrotdir = $options{versiondir};
-
-# We'll report multiple occurrences of the same file
-my %seen;
-
-my @files;
-my @installable_exe;
-my %directories;
- at ARGV = @manifests;
-while (<>) {
- chomp;
-
- s/\#.*//; # Ignore comments
- next if /^\s*$/; # Skip blank lines
-
- my ( $src, $meta, $dest ) = split( /\s+/, $_ );
- $dest ||= $src;
-
- if ( $seen{$src}++ ) {
- print STDERR "$ARGV:$.: Duplicate entry $src\n";
- }
-
- # Parse out metadata
- die "Malformed line in MANIFEST: $_" if not defined $meta;
- my $generated = $meta =~ s/^\*//;
- my ($package) = $meta =~ /^\[(.*?)\]/;
- $meta =~ s/^\[(.*?)\]//;
- next unless $package; # Skip if this file belongs to no package
-
- next unless $package =~ /main|library|pge/;
-
- my %meta;
- @meta{ split( /,/, $meta ) } = ();
- $meta{$_} = 1 for ( keys %meta ); # Laziness
-
- if ( /^runtime/ ) {
- # have to catch this case early.
- $dest =~ s/^runtime\/parrot\///;
- $dest = File::Spec->catdir( $options{libdir}, $parrotdir, $dest );
- }
- elsif ( $meta{lib} ) {
- if ( $dest =~ /^install_/ ) {
- $dest =~ s/^install_//; # parrot with different config
- $dest = File::Spec->catdir( $options{libdir}, $parrotdir, 'include', $dest );
- }
- else {
- # don't allow libraries to be installed into subdirs of libdir
- $dest = File::Spec->catdir( $options{libdir}, basename($dest) );
- }
- }
- elsif ( $meta{bin} ) {
- my $copy = $dest;
- $dest =~ s/^installable_//; # parrot with different config
- $dest = File::Spec->catdir( $options{bindir}, $dest );
- # track bin here to check later below
- # https://trac.parrot.org/parrot/ticket/434
- if ( $copy =~ /^installable/ ) {
- push @installable_exe, [ $src, $dest ];
- next;
- }
- }
- elsif ( $meta{include} ) {
- $dest =~ s/^include//;
- $dest = File::Spec->catdir( $options{includedir}, $parrotdir, $dest );
- }
- elsif ( $meta{doc} ) {
- $dest =~ s/^docs\/resources/resources/; # resources go in the top level of docs
- $dest =~ s/^docs/pod/; # other docs are actually raw Pod
- $dest = File::Spec->catdir( $options{docdir}, $parrotdir, $dest );
- }
- elsif ( $meta{pkgconfig} ) {
-
- # For the time being this is hardcoded as being installed under libdir
- # as it is typically done with automake installed packages. If there
- # is a use case to make this configurable we'll add a seperate
- # --pkgconfigdir option.
- $dest = File::Spec->catdir( $options{libdir}, 'pkgconfig', $parrotdir, $dest );
- }
- elsif ( /^compilers/ ) {
- $dest =~ s/^compilers/languages/;
- $dest = File::Spec->catdir( $options{libdir}, $parrotdir, $dest );
- }
- else {
- die "Unknown install location in MANIFEST: $_";
- }
-
- $dest = File::Spec->catdir( $options{buildprefix}, $dest )
- if $options{buildprefix};
-
- $directories{ dirname($dest) } = 1;
- push( @files, [ $src => $dest ] );
-}
-continue {
- close ARGV if eof; # Reset line numbering for each input file
-}
-
-unless ( $options{'dry-run'} ) {
- for my $dir ( map { $options{destdir} . $_ } keys %directories ) {
- unless ( -d $dir ) {
-
- # Make full path to the directory $dir
- my @dirs;
- while ( !-d $dir ) { # Scan up to nearest existing ancestor
- unshift @dirs, $dir;
- $dir = dirname($dir);
- }
- foreach my $d (@dirs) {
- mkdir( $d, 0777 ) or die "mkdir $d: $!\n";
- }
- }
- }
-}
-
-for my $iref (@installable_exe) {
- my ( $i, $dest ) = @{ $iref };
- my ($file) = $i =~ /installable_(.+)$/;
- next unless $file;
- my @f = map { $_ ? $_->[0] : '' } @files;
- if (grep(/^$file$/, @f)) {
- if (-e $file) {
- print "skipping $file, using installable_$file instead\n";
- @files = map {$_ and $_->[0] !~ /^$file$/ ? $_ : undef} @files;
- }
- }
-}
-# for every .exe check if there's an installable. Fail if not
-foreach my $fref (@files ) {
- next unless $fref;
- my ( $src, $dest ) = @{ $fref };
- my $i;
- # This logic will fail on non-win32 if the generated files are really
- # generated as with rt #40817. We don't have [main]bin here.
- $i = "installable_$src" if $src =~ /\.exe$/;
- next unless $i;
- unless (map {$_->[0] =~ /^$i$/} @installable_exe) {
- die "$i is missing in MANIFEST or MANIFEST.generated\n";
- }
-}
-print("Installing ...\n");
-foreach my $fref ( @files, @installable_exe ) {
- next unless $fref;
- my ( $src, $dest ) = @{ $fref };
- $dest = $options{destdir} . $dest;
- if ( $options{'dry-run'} ) {
- print "$src -> $dest\n";
- next;
- }
- else {
- next unless -e $src;
- next if $^O eq 'cygwin' and -e "$src.exe"; # stat works, copy not
- copy( $src, $dest ) or die "copy $src to $dest: $!\n";
- print "$dest\n";
- }
- my $mode = ( stat($src) )[2];
- chmod $mode, $dest;
-}
-
-################################################################################
-
=head1 TITLE
tools/dev/install_files.pl - Copy files to their correct locations
@@ -298,6 +108,163 @@
=cut
+################################################################################
+
+use strict;
+use warnings;
+use File::Basename qw(basename);
+use lib qw( lib );
+use Parrot::Install qw(
+ install_files
+ create_directories
+ lines_to_files
+);
+
+# When run from the makefile, which is probably the only time this
+# script will ever be used, all of these defaults will get overridden.
+my %options = (
+ buildprefix => '',
+ prefix => '/usr',
+ destdir => '',
+ exec_prefix => '/usr',
+ bindir => '/usr/bin',
+ libdir => '/usr/lib', # parrot/ subdir added below
+ includedir => '/usr/include', # parrot/ subdir added below
+ docdir => '/usr/share/doc', # parrot/ subdir added below
+ versiondir => '',
+ 'dry-run' => 0,
+ packages => 'main|library|pge',
+);
+
+my @manifests;
+foreach (@ARGV) {
+ if (/^--([^=]+)=(.*)/) {
+ $options{$1} = $2;
+ }
+ else {
+ push @manifests, $_;
+ }
+}
+
+my $parrotdir = $options{versiondir};
+
+# Set up transforms on filenames
+my(@transformorder) = qw(lib bin include doc pkgconfig ^compilers);
+my(%metatransforms) = (
+ lib => {
+ ismeta => 1,
+ optiondir => 'lib',
+ transform => sub {
+ my($filehash) = @_;
+ local($_) = $filehash->{Dest};
+ if ( /^install_/ ) {
+ s/^install_//; # parrot with different config
+ $filehash->{DestDirs} = [$parrotdir, 'include'];
+ $filehash->{Dest} = $_;
+ }
+ else {
+ # don't allow libraries to be installed into subdirs of libdir
+ $filehash->{Dest} = basename($_);
+ }
+ return($filehash);
+ },
+ },
+ bin => {
+ ismeta => 1,
+ optiondir => 'bin',
+ transform => sub {
+ my($filehash) = @_;
+ # parrot with different config
+ $filehash->{Installable} = $filehash->{Dest} =~ s/^installable_//;
+ return($filehash);
+ },
+ isbin => 1,
+ },
+ include => {
+ ismeta => 1,
+ optiondir => 'include',
+ transform => sub {
+ my($filehash) = @_;
+ $filehash->{Dest} =~ s/^include//;
+ $filehash->{DestDirs} = [$parrotdir];
+ return($filehash);
+ },
+ },
+ doc => {
+ ismeta => 1,
+ optiondir => 'doc',
+ transform => sub {
+ my($filehash) = @_;
+ $filehash->{Dest} =~ s#^docs/resources#resources#; # resources go in the top level of docs
+ $filehash->{Dest} =~ s/^docs/pod/; # other docs are actually raw Pod
+ $filehash->{DestDirs} = [$parrotdir];
+ return($filehash);
+ },
+ },
+ pkgconfig => {
+ ismeta => 1,
+ optiondir => 'lib',
+ transform => sub {
+ my($filehash) = @_;
+ # For the time being this is hardcoded as being installed under
+ # libdir as it is typically done with automake installed packages.
+ # If there is a use case to make this configurable we'll add a
+ # seperate --pkgconfigdir option.
+ $filehash->{DestDirs} = ['pkgconfig', $parrotdir];
+ return($filehash);
+ },
+ },
+ '^compilers' => {
+ optiondir => 'lib',
+ transform => sub {
+ my($filehash) = @_;
+ $filehash->{Dest} =~ s/^compilers/languages/;
+ $filehash->{DestDirs} = [$parrotdir];
+ return($filehash);
+ },
+ },
+);
+
+my($filehashes, $directories) = lines_to_files(
+ \%metatransforms, \@transformorder, \@manifests, \%options, $parrotdir
+);
+
+unless ( $options{'dry-run'} ) {
+ create_directories($options{destdir}, $directories);
+}
+
+# TT #347
+# 1. skip build_dir-only binaries for files marked Installable
+my($filehash, @removes, $removes);
+foreach $filehash (grep { $_->{Installable} } @$filehashes) {
+ my( $src, $dest ) = map { $filehash->{$_} } qw(Source Dest);
+ my ($file) = $src =~ /installable_(.+)$/;
+ next unless $file;
+ if((grep { $_->{Source} =~ /^$file$/ } @$filehashes) and -e $file) {
+ print "skipping $file, using installable_$file instead\n";
+ push @removes, $file;
+ }
+}
+$removes = join '|', @removes;
+@$filehashes = grep { $_->{Source} !~ /^($removes)$/ } @$filehashes;
+
+# 2. for every .exe check if there's an installable. Fail if not
+my $i;
+foreach $filehash (grep { ! $_->{Installable} } @$filehashes ) {
+ my( $src, $dest ) = map { $filehash->{$_} } qw(Source Dest);
+ next unless $src =~ /\.exe$/;
+ # This logic will fail on non-win32 if the generated files are really
+ # generated as with rt #40817. We don't have [main]bin here.
+ $i = "installable_$src";
+ unless (map {$_->{Source} =~ /^$i$/} grep { $_->{Installable} } @$filehashes) {
+ die "$i is missing in MANIFEST or MANIFEST.generated\n";
+ }
+}
+
+install_files($options{destdir}, $options{'dry-run'}, $filehashes);
+
+print "Finished install_files.pl\n";
+
# Local Variables:
# mode: cperl
# cperl-indent-level: 4
Modified: trunk/tools/dev/mk_language_shell.pl
==============================================================================
--- trunk/tools/dev/mk_language_shell.pl Mon May 25 00:47:41 2009 (r39164)
+++ trunk/tools/dev/mk_language_shell.pl Mon May 25 01:15:28 2009 (r39165)
@@ -492,7 +492,7 @@
VERSION := @versiondir@
BIN_DIR := @bindir@
LIB_DIR := @libdir@$(VERSION)
-DOC_DIR := @doc_dir@$(VERSION)
+DOC_DIR := @docdir@$(VERSION)
MANDIR := @mandir@$(VERSION)
# Set up extensions
More information about the parrot-commits
mailing list