1#!/usr/bin/perl -w                                         # -*- perl -*-
2
3use strict;
4use warnings;
5
6use 5.006;
7use lib qw( ./lib );
8use Config;
9use File::Spec::Functions qw( catfile );
10use Template;
11use ExtUtils::MakeMaker;
12use Cwd;
13
14select STDERR;
15$| = 1;
16select STDOUT;
17
18use vars qw( $TT_VERSION $TT_PREFIX
19             $TT_XS_ENABLE $TT_XS_DEFAULT
20             $TT_QUIET $TT_ACCEPT $TT_YES );
21
22# check O/S to set sensible defaults
23
24my ($WIN32, $FLAVOUR, $PREFIX, $IMAGES, $MAKE);
25if ($^O eq 'MSWin32') {  # any others also?
26    $WIN32   = 1;
27    $FLAVOUR = 'Win32';
28    $PREFIX  = 'C:/Program Files/Template Toolkit 2';
29    $IMAGES  = '/tt2/images';
30}
31else {
32    $WIN32   = 0;
33    $FLAVOUR = 'Unix';
34    $PREFIX  = '/usr/local/tt2';
35    $IMAGES  = '/tt2/images';
36}
37$MAKE=$Config{'make'};
38
39
40# read command line args putting TT_* into $ttconfig and
41# everything else (regular Makefile.PL args, e.g. PREFIX)
42# goes into $config
43
44my (%config, %ttconfig);
45while ($_ = shift) {
46    my ($k, $v) = split(/=/, $_, 2);
47    if ($k =~ /^TT/) {
48        $ttconfig{ $k } = $v || 0;
49    }
50    else {
51        $config{ $k } = $v || 0;
52    }
53};
54
55
56# print help if they asked for it
57
58if (exists $ttconfig{ TT_HELP }) {
59    print <<EOF;
60The following options can be specified as command line
61arguments to 'perl Makefile.PL'.  e.g.
62
63  perl Makefile.PL TT_XS_DEFAULT=y TT_ACCEPT=y
64
65  TT_XS_ENABLE   Enable XS Stash         (y)
66  TT_XS_DEFAULT  Use XS Stash by default (y)
67  TT_QUIET       no messages             (n)
68  TT_ACCEPT      accept defaults         (n)
69
70By default, the Makefile.PL runs in interactive mode,
71prompting for confirmation of the various configuration
72options.  Setting the TT_ACCEPT option causes the default
73value (possibly modified by other command line options)
74to be accepted.  The TT_QUIET option can also be set to
75suppress the prompt messages.
76
77EOF
78    exit(0);
79}
80
81# these global package variables are the main flags used
82# in this script, here defaulted to sensible values
83
84$TT_VERSION       = $Template::VERSION;
85$TT_XS_ENABLE     = 'y';
86$TT_XS_DEFAULT    = 'y';
87$TT_QUIET         = 'n';
88$TT_ACCEPT        = 'n';
89
90my $DEFAULTS_FILE   = '.defaults.cfg';
91my $DEFAULTS = '';
92
93if (-f $DEFAULTS_FILE) {
94    require $DEFAULTS_FILE;
95    $DEFAULTS = " read from '$DEFAULTS_FILE'";
96}
97
98$TT_XS_ENABLE     = $ttconfig{ TT_XS_ENABLE  } if defined $ttconfig{ TT_XS_ENABLE  };
99$TT_XS_DEFAULT    = $ttconfig{ TT_XS_DEFAULT } if defined $ttconfig{ TT_XS_DEFAULT };
100$TT_QUIET         = $ttconfig{ TT_QUIET      } if defined $ttconfig{ TT_QUIET      };
101
102if (defined $ttconfig{ TT_ACCEPT }) {
103    $TT_ACCEPT = $ttconfig{ TT_ACCEPT };
104}
105else {
106    # standard behaviour for MakeMaker to indicate accept all defaults
107    $TT_ACCEPT = $ENV{PERL_MM_USE_DEFAULT} ? 'y' : 'n';
108}
109
110foreach ($TT_XS_ENABLE, $TT_XS_DEFAULT ) {
111    $_ = 'n' if ! $_;
112}
113$TT_ACCEPT = 0 if $TT_ACCEPT eq 'n';
114$TT_QUIET  = 0 if $TT_QUIET eq 'n';
115$TT_QUIET  = 0 unless $TT_ACCEPT;
116
117# define version numbers of required modules
118my $TT_APPCONFIG_VERSION = '1.56';
119my $TT_FILE_SPEC_VERSION = '0.8';
120my $TT_FILE_TEMP_VERSION = '0.12';
121
122
123#========================================================================
124
125welcome_message();
126version_check();
127mandatory_modules();
128optional_stash_xs();
129write_defaults();
130
131print "\n";
132
133
134#------------------------------------------------------------------------
135# build options and write Makefile
136#------------------------------------------------------------------------
137
138package main;
139
140my %opts = (
141    %config,
142    'NAME'             => 'Template',
143    'DISTNAME'     => 'Template-Toolkit',
144    'VERSION_FROM' => 'lib/Template.pm',
145    'EXE_FILES'    => [ 'bin/tpage', 'bin/ttree' ],
146    'PMLIBDIRS'    => [ 'lib' ],
147    'DIR'          => [ ],
148    'PREREQ_PM'    => {
149        'AppConfig'    => $TT_APPCONFIG_VERSION,
150        'File::Spec'   => $TT_FILE_SPEC_VERSION,
151        'File::Temp'   => $TT_FILE_TEMP_VERSION,
152        'Scalar::Util' => 0,
153    },
154    'dist'         => {
155        'COMPRESS' => 'gzip',
156        'SUFFIX'   => 'gz',
157    },
158    'test'         => {
159        'TESTS'    => join(' ', map { glob } qw( t/*.t t/vmethods/*.t )),
160    },
161    'clean'        => {
162        'FILES'        => join(' ', qw( docs/ttree.cfg
163                                        examples/ttree.cfg
164                                        t/dbi_test.cfg
165                                        t/test/src/baz.ttc
166                                        t/test/src/complex.org
167                                        t/test/src/complex.ttc
168                                        t/test/src/evalperl.ttc
169                                        t/test/src/foo.ttc )),
170    },
171);
172
173push @{ $opts{'DIR'} }, 'xs' if $TT_XS_ENABLE;
174
175# Handle dev versions in our check
176my $mmv = $ExtUtils::MakeMaker::VERSION;
177$mmv =~ s/\_.+//;
178
179if ($mmv >= 5.43) {
180    $opts{ AUTHOR   } = 'Andy Wardley <abw@wardley.org>';
181    $opts{ ABSTRACT } = 'comprehensive template processing system',
182}
183
184if ($ExtUtils::MakeMaker::VERSION ge '6.30_00') {
185    $opts{'LICENSE' } = 'perl';
186}
187
188WriteMakefile( %opts );
189
190    print <<EOF;
191
192Configuration complete.  You should now run '$MAKE', '$MAKE test' and
193then '$MAKE install'.   See the README file for further information.
194EOF
195
196
197#========================================================================
198
199
200
201#------------------------------------------------------------------------
202# welcome_message()
203#
204# Print opening banner.
205#------------------------------------------------------------------------
206
207sub welcome_message {
208    print(<<EOF);
209
210                    Template Toolkit Version $TT_VERSION
211                    =============================
212
213Using $FLAVOUR defaults$DEFAULTS.
214Run 'perl Makefile.PL TT_HELP' for a summary of options.
215EOF
216    print "Messages suppressed (TT_QUIET).  " if $TT_QUIET;
217    print "Accepting defaults automatically (TT_ACCEPT)." if $TT_ACCEPT;
218}
219
220
221
222#------------------------------------------------------------------------
223# version_check()
224#
225# Check for pre-version 2.00 installation and issue warning
226#------------------------------------------------------------------------
227
228sub version_check {
229    eval "use Template";
230    unless ($@ or $Template::VERSION =~ /^2/) {
231        warn(<<EOF) unless $TT_QUIET;
232
233IMPORTANT NOTE:
234
235    You have version $Template::VERSION of the Template Toolkit installed.
236
237    There are some minor incompatabilities between version 1 and 2
238    of the Template Toolkit which you should be aware of.  Installing
239    this version will overwrite your version $Template::VERSION files
240    unless you take measures to install one or the other version in a
241    different location (i.e. perl Makefile.PL PREFIX=/other/path).
242
243    Please consult the README and Changes file for further details.
244    Most of the changes are in the more obscure features and
245    directives so hopefully you will find the upgrade process fairly
246    painless.  If you're feeling brave, then answer 'y', otherwise 'n'.
247
248EOF
249        exit unless ttprompt("Do you want to continue?", 'y') =~ /y/i;
250    }
251}
252
253
254#------------------------------------------------------------------------
255# mandatory_modules()
256#
257# Detect mandatory module
258#------------------------------------------------------------------------
259
260sub mandatory_modules {
261    eval "use AppConfig";
262    if ($@ or $AppConfig::VERSION < $TT_APPCONFIG_VERSION) {
263        warn(<<EOF);
264
265The Template Toolkit requires that the AppConfig module (version $TT_APPCONFIG_VERSION
266or later) first be installed.  This is used by
267the 'ttree' program for reading command line options and configuration
268files.  It is available from CPAN:
269
270    http://www.cpan.org/authors/Andy_Wardley/
271
272EOF
273    }
274
275    eval "use File::Spec";
276    if ($@ or $File::Spec::VERSION < $TT_FILE_SPEC_VERSION) {
277        warn(<<EOF);
278
279The Template Toolkit requires that the File::Spec module (version $TT_FILE_SPEC_VERSION
280or later) first be installed.  This is used by the File plugin.  It is
281available from CPAN:
282
283    http://search.cpan.org/search?dist=File-Spec
284
285EOF
286    }
287
288    eval "use File::Temp";
289    if ($@ or $File::Temp::VERSION < $TT_FILE_TEMP_VERSION) {
290        warn(<<EOF);
291
292The Template Toolkit requires that the File::Temp module (version $TT_FILE_TEMP_VERSION
293or later) first be installed.  This is used by the Template::Document
294class for storing compiled templates.  It is available from CPAN:
295
296    http://search.cpan.org/search?dist=File-Temp
297
298EOF
299    }
300}
301
302
303#------------------------------------------------------------------------
304# optional_stash_xs()
305#
306# Prompt for installation and default use of XS Stash.
307#------------------------------------------------------------------------
308
309sub optional_stash_xs {
310#    return if $TT_ACCEPT && (! $TT_XS_ENABLE || $TT_XS_ENABLE eq 'n');
311
312    message(<<EOF);
313
314
315Template::Stash::XS
316-------------------
317
318The Template::Stash module is a core part of the Template Toolkit,
319implementing the magic for accessing data using the dot notation.
320
321There is a high speed version, Template::Stash::XS, written in C.
322This makes the Template Toolkit run about twice as fast as when using
323the regular Template::Stash written in Perl.  If you've got a C
324compiler on your system then you can elect to have the XS Stash built.
325You can also specify that you want to use the XS Stash by default.
326
327Note that as of version 2.15 the XS Stash now supports access to tied
328hashes and arrays.
329
330See 'perldoc Template::Config' for further details.
331
332EOF
333
334    $TT_XS_ENABLE = (ttprompt('Do you want to build the XS Stash module?',
335                              $TT_XS_ENABLE) =~ /^y/i);
336
337    if ($TT_XS_ENABLE) {
338        $TT_XS_DEFAULT =
339            (ttprompt('Do you want to use the XS Stash by default?',
340                      $TT_XS_DEFAULT) =~ /^y/i);
341    }
342    else {
343        # If the XS stash is disabled, we cannot use it as the default stash.
344        $TT_XS_DEFAULT = 0;
345    }
346
347    # Actually, we would have to fix 'Config.pm' only if the XS stash is
348    # disabled. But this way, we are sure the correct module is used.
349        fix_file(catfile('lib','Template','Config.pm'),
350                 '$STASH',
351                 $TT_XS_DEFAULT ? 'Template::Stash::XS' : 'Template::Stash');
352}
353
354
355
356
357
358#--------------------------------------------------------------------
359# write_defaults()
360#
361# write configuration defaults to file
362#--------------------------------------------------------------------
363
364sub write_defaults {
365    open(FP, "> $DEFAULTS_FILE") || die "$DEFAULTS_FILE: $!\n";
366    my ( $ttxs_enable, $ttxs_default )
367            = map { $_ ? 'y' : 'n' }
368            ( $TT_XS_ENABLE, $TT_XS_DEFAULT );
369    print FP <<EOF;
370\$TT_XS_ENABLE     = '$ttxs_enable';
371\$TT_XS_DEFAULT    = '$ttxs_default';
372\$TT_ACCEPT        = '$TT_ACCEPT';
373\$TT_QUIET         = '$TT_QUIET';
3741;
375EOF
376    close(FP);
377}
378
379
380
381
382#------------------------------------------------------------------------
383# fix_file($file, $find, $fix)
384#
385# Fixes a variable definition in a file.  e.g.
386# fix_file('templates/splash/config', 'images', '/tt2/splash')
387#------------------------------------------------------------------------
388
389sub fix_file {
390    my ($file, $find, $fix) = @_;
391    local *FP;
392    local $/ = undef;
393
394    $find = quotemeta($find);
395
396    open(FP, "< $file") || die "$file: $!\n";
397    my $text = <FP>;
398    close(FP);
399
400    ($text =~ s/^(\s*${find}\s*=\s*)'.*?'/$1'$fix'/m)
401        || die "$find not found in $file\n";
402
403    open(FP, "> $file") || die "$file: $!\n";
404    print FP $text;
405    close(FP);
406}
407
408
409#------------------------------------------------------------------------
410# find_program($path, $prog)
411#
412# Find a program, $prog, by traversing the given directory path, $path.
413# Returns full path if the program is found.
414#
415# Written by Craig Barratt, Richard Tietjen add fixes for Win32.
416#
417# abw changed name from studly caps findProgram() to find_program() :-)
418#------------------------------------------------------------------------
419
420sub find_program {
421    my($path, $prog) = @_;
422#     my $sep = $WIN32 ? qr/;/ : qr/:/;
423#     foreach my $dir ( split($sep, $path) ) {
424    foreach my $dir ( split($Config{path_sep}, $path) ) {
425        my $file = File::Spec->catfile($dir, $prog);
426        if ( !$WIN32 ) {
427            return $file if ( -x $file );
428        } else {
429            # Windows executables end in .xxx, exe precedes .bat and .cmd
430            foreach my $dx ( qw/exe bat cmd/ ) {
431                return "$file.$dx" if ( -x "$file.$dx" );
432            }
433        }
434    }
435}
436
437
438#------------------------------------------------------------------------
439# message($text)
440#
441# Print message unless quiet mode.
442#------------------------------------------------------------------------
443
444sub message {
445    return if $TT_QUIET;
446    print @_;
447}
448
449
450#------------------------------------------------------------------------
451# ttprompt($message, $default)
452#------------------------------------------------------------------------
453
454sub ttprompt {
455    my ($msg, $def)=@_;
456    my $ISA_TTY = -t STDIN && (-t STDOUT || !(-f STDOUT || -c STDOUT)) ; # Pipe?
457    my $dispdef = defined $def ? "[$def] " : " ";
458    $def = defined $def ? $def : "";
459    my $ans = '';
460    local $|=1;
461    print "$msg $dispdef" unless $TT_QUIET;
462    if ($TT_ACCEPT || ! $ISA_TTY) {
463        print "$def\n" unless $TT_QUIET;
464    }
465    else {
466        chomp($ans = <STDIN>);
467    }
468    return ($ans ne '') ? $ans : $def;
469}
470
471
472#------------------------------------------------------------------------
473# yep($text)
474#------------------------------------------------------------------------
475
476sub yep {
477    return if $TT_QUIET;
478    print '[X] ', shift, "\n";
479}
480
481
482#------------------------------------------------------------------------
483# nope($text)
484#------------------------------------------------------------------------
485sub nope {
486    return if $TT_QUIET;
487    print '[ ] ', shift, "\n";
488}
489