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 );
