package IkiWiki::FakeSetup; use strict; use warnings; use Data::Dumper qw( ); use Exporter qw( import ); our @EXPORT_OK = qw( readSetup writeSetup ); sub readSetup { my ( $setupfile ) = @_; # Sorry about the use of globals but it's hard to share lexicals with dynamically generated source. $IkiWiki::FakeSetup::package = undef; @IkiWiki::FakeSetup::args = (); sub inc { my ( $self, $file ) = @_; my $package = $file; $package =~ s/\//::/g; $package =~ s/\.pm//; my @src = ( "package $package;\n" , "sub import {\n" , " my ( \$class, \@args ) = \@_;\n" , " \$IkiWiki::FakeSetup::package = \$class;\n" , " \@IkiWiki::FakeSetup::args = \@args;\n" , "}\n" , "1;\n" ); return sub { if ( scalar @src ) { $_ = shift @src; return 1; } else { return 0; } }; }; eval { my @oldINC = @INC; @INC = ( ".", \&inc ); my %oldINC = %INC; %INC = ( ); do $setupfile; @INC = @oldINC; %INC = %oldINC; }; return ( $IkiWiki::FakeSetup::package, @IkiWiki::FakeSetup::args ); } sub writeSetup { my ( $package, @args ) = @_; my $d = Data::Dumper->new( \@args ); $d->Terse( 1 ); return "#!/usr/bin/perl\n\nuse $package " . $d->Dump( ) . ";\n"; } 1; __END__ Because it may not be completely obvious, here's how you would use this: #!/usr/bin/perl use strict; use warnings; use IkiWiki::FakeSetup qw( readSetup writeSetup ); # This reads the setup file, returning the package it uses and any configuration it passed to that package. my ( $package, $config ) = readSetup( "almighty_ikiwiki_template.setup" ); # Make changes to the configuration. $config->{"srcdir"} = "/some/dir"; $config->{"adminemail"} = "somejerk\@jerkville.com"; # Open a new file, and write the changed configuration to it. open( SETUP, ">", "almighty_ikiwiki_template_changed.setup" ); print SETUP writeSetup( $package, $config ); close( SETUP );