Re: Sharedir for Module::Build

"Curtis Jewell" <[email protected]>
Newsgroups gmane.comp.lang.perl.modules.module-build
Message-ID <[email protected]>
This should be close to executable, (I pulled it out of another project
of mine) and once cleaned up, should do the trick:

(It's from
http://svn.ali.as/cpan/trunk/Module-Build-Functions/lib/Module/Build/Functions.pm,
which is meant to give an M::I -style interface to Module::Build - I
just haven't had the tuits to work on it lately.  It's tested, it just
needs a little help to get it into a straight M::B format.)

All modules used are in core as of 5.005.

[I test on a Win32 system, so files are tracked both in a Unix format
(for MANIFEST purposes) and the current $^O's format.]

--Curtis Jewell

my %ARGS;

sub _scan_dir {
	my ( $srcdir, $destdir, $unixdir, $type, $files ) = @_;

	my $type_files = $type . '_files';

	$ARGS{$type_files} = {} unless exists $ARGS{"$type_files"};

	my $dir_handle;

	if ( $] < 5.006 ) {
		require Symbol;
		$dir_handle = Symbol::gensym();
	}

	opendir $dir_handle, $srcdir or croak $!;

  FILE:
	foreach my $direntry ( readdir $dir_handle ) {
		if ( -d catdir( $srcdir, $direntry ) ) {
			next FILE if ( $direntry eq q{.} );
			next FILE if ( $direntry eq q{..} );
			_scan_dir(
				catdir( $srcdir,  $direntry ),
				catdir( $destdir, $direntry ),
				File::Spec::Unix->catdir( $unixdir, $direntry ),
				$type,
				$files
			);
		} else {
			my $sourcefile = catfile( $srcdir, $direntry );
			my $unixfile = File::Spec::Unix->catfile( $unixdir, $direntry );
			if ( exists $files->{$unixfile} ) {
				$ARGS{$type_files}{$sourcefile} =
				  catfile( $destdir, $direntry );
			}
		}
	} ## end foreach my $direntry ( readdir...

	closedir $dir_handle;

	return;
} ## end sub _scan_dir

sub install_share {
	my $dir  = @_ ? pop   : 'share';
	my $type = @_ ? shift : 'dist';

	unless ( defined $type
		and ( ( $type eq 'module' ) or ( $type eq 'dist' ) ) )
	{
		croak "Illegal or invalid share dir type '$type'";
	}
	unless ( defined $dir and -d $dir ) {
		croak 'Illegal or missing directory install_share param';
	}

	require File::Spec::Unix;
	require ExtUtils::Manifest;
	my $files = ExtUtils::Manifest::maniread();
	if (0 == scalar (%files)) {
		croak 'Empty or no MANIFEST file';
	}
	my $installation_path;
	my $sharecode;

	if ( $type eq 'dist' ) {
		croak 'Too many parameters to install_share' if @_;

		my $dist = $ARGS{'dist_name'};

		$installation_path =
		  catdir( _installdir(), qw(auto share dist), $dist );
		_scan_dir( $dir, 'share', $dir, 'share', $files );
		push @install_types, 'share';
		$sharecode = 'share';
	} else {
		my $module = shift;

		unless ( defined $module ) {
			croak "Missing or invalid module name '$module'";
		}

		$module =~ s/::/-/g;
		$installation_path =
		  catdir( _installdir(), qw(auto share module), $module );
		$sharecode = 'share_d' . $sharemod_used;
		_scan_dir( $dir, $sharecode, $dir, $sharecode, $files );
		push @install_types, $sharecode;
		$sharemod_used++;
	} ## end else [ if ( $type eq 'dist' )

	# Set the path to install to.
	install_path( $sharecode, $installation_path );

	# This helps for testing purposes...
	if ( $Module::Build::VERSION >= 0.31 ) {
		Module::Build->add_property( $sharecode . '_files',
			default => sub { return {} } );
	}

	# 99% of the time we don't want to index a shared dir
	no_index($dir);

	# This construction requires 0.26.
	_mb_required('0.26');
	return;
} ## end sub install_share


On Sat, 08 Aug 2009 15:10 +0200, "Thomas Klausner" <[email protected]>
wrote:
> Hi!
> 
> So, to put my SDL-base Spaceinvaders game [0] on CPAN I need to install
> some 
> stuff (images) alongside my dist. Previously I used several different 
> homegrown techniques for this, which work. But I'd rather use the sort 
> of common File::ShareDir instead of rolling my own. Unfortunatly, 
> Module::Build does not support actually installing stuff that 
> File::ShareDir can later find out of the box. 
> 
> I could now (again) fuzz around add_build_element, install_path etc, but 
> I'd rather put all of this into a reusable module, i.e. something like 
> File::Share::Install or Module::Install::Share, only for Module::Build.
> 
> First question: Does this exist already? Or is there some easy way using 
> Module::Build to say "take all the stuff in this dir and install it to 
> where File::ShareDir would look for it"?
> 
> Second question: Instead of writing a subclass of Module::Build and put 
> that on CPAN I'd rather implement this as a mixin (i.e. a distribution 
> that exports some methods that then can be used by a standard 
> Module::Build instance). What do you think about that?
> 
> For the API, I'd like to have something like
> 
>    $builder->install_share(@list_of_dirs);
> 
> This would go through all the dirs, add the files in these dirs to the 
> configuration ('share_files'), add a correct install_path, call 
> add_build_elements, maybe add those files to no_index, ..
> 
> Any more feedback/ideas?
> 
> 
> 0: http://github.com/domm/Game-PerlInvaders
> 
> -- 
> #!/usr/bin/perl                              http://domm.plix.at
> for(ref bless{},just'another'perl'hacker){s-:+-$"-g&&print$_.$/}
--
Curtis Jewell
[email protected]

%DCL-E-MEM-BAD, bad memory
-VMS-F-PDGERS, pudding between the ears

[I use PC-Alpine, which deliberately does not display colors and pictures in HTML mail]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.