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    'META_MERGE' => {
155        'resources' => {
156            'repository' => 'https://github.com/abw/Template2',
157        },
158    },
159    'dist'         => {
160        'COMPRESS' => 'gzip',
161        'SUFFIX'   => 'gz',
162    },
163    'test'         => {
164        'TESTS'    => join(' ', map { glob } qw( t/*.t t/vmethods/*.t )),
165    },
166    'clean'        => {
167        'FILES'        => join(' ', qw( docs/ttree.cfg
168                                        examples/ttree.cfg
169                                        t/dbi_test.cfg
170                                        t/test/src/baz.ttc
171                                        t/test/src/complex.org
172                                        t/test/src/complex.ttc
173                                        t/test/src/evalperl.ttc
174                                        t/test/src/foo.ttc )),
175    },
176);
177
178push @{ $opts{'DIR'} }, 'xs' if $TT_XS_ENABLE;
179
180# Handle dev versions in our check
181my $mmv = $ExtUtils::MakeMaker::VERSION;
182$mmv =~ s/\_.+//;
183
184if ($mmv >= 5.43) {
185    $opts{ AUTHOR   } = 'Andy Wardley <abw@wardley.org>';
186    $opts{ ABSTRACT } = 'comprehensive template processing system',
187}
188
189if ($ExtUtils::MakeMaker::VERSION ge '6.30_00') {
190    $opts{'LICENSE' } = 'perl';
191}
192
193WriteMakefile( %opts );
194
195    print <<EOF;
196
197Configuration complete.  You should now run '$MAKE', '$MAKE test' and
198then '$MAKE install'.   See the README file for further information.
199EOF
200
201
202#========================================================================
203
204
205
206#------------------------------------------------------------------------
207# welcome_message()
208#
209# Print opening banner.
210#------------------------------------------------------------------------
211
212sub welcome_message {
213    print(<<EOF);
214
215                    Template Toolkit Version $TT_VERSION
216                    =============================
217
218Using $FLAVOUR defaults$DEFAULTS.
219Run 'perl Makefile.PL TT_HELP' for a summary of options.
220EOF
221    print "Messages suppressed (TT_QUIET).  " if $TT_QUIET;
222    print "Accepting defaults automatically (TT_ACCEPT)." if $TT_ACCEPT;
223}
224
225
226
227#------------------------------------------------------------------------
228# version_check()
229#
230# Check for pre-version 2.00 installation and issue warning
231#------------------------------------------------------------------------
232
233sub version_check {
234    eval "use Template";
235    unless ($@ or $Template::VERSION =~ /^2/) {
236        warn(<<EOF) unless $TT_QUIET;
237
238IMPORTANT NOTE:
239
240    You have version $Template::VERSION of the Template Toolkit installed.
241
242    There are some minor incompatabilities between version 1 and 2
243    of the Template Toolkit which you should be aware of.  Installing
244    this version will overwrite your version $Template::VERSION files
245    unless you take measures to install one or the other version in a
246    different location (i.e. perl Makefile.PL PREFIX=/other/path).
247
248    Please consult the README and Changes file for further details.
249    Most of the changes are in the more obscure features and
250    directives so hopefully you will find the upgrade process fairly
251    painless.  If you're feeling brave, then answer 'y', otherwise 'n'.
252
253EOF
254        exit unless ttprompt("Do you want to continue?", 'y') =~ /y/i;
255    }
256}
257
258
259#------------------------------------------------------------------------
260# mandatory_modules()
261#
262# Detect mandatory module
263#------------------------------------------------------------------------
264
265sub mandatory_modules {
266    eval "use AppConfig";
267    if ($@ or $AppConfig::VERSION < $TT_APPCONFIG_VERSION) {
268        warn(<<EOF);
269
270The Template Toolkit requires that the AppConfig module (version $TT_APPCONFIG_VERSION
271or later) first be installed.  This is used by
272the 'ttree' program for reading command line options and configuration
273files.  It is available from CPAN:
274
275    http://www.cpan.org/authors/Andy_Wardley/
276
277EOF
278    }
279
280    eval "use File::Spec";
281    if ($@ or $File::Spec::VERSION < $TT_FILE_SPEC_VERSION) {
282        warn(<<EOF);
283
284The Template Toolkit requires that the File::Spec module (version $TT_FILE_SPEC_VERSION
285or later) first be installed.  This is used by the File plugin.  It is
286available from CPAN:
287
288    http://search.cpan.org/search?dist=File-Spec
289
290EOF
291    }
292
293    eval "use File::Temp";
294    if ($@ or $File::Temp::VERSION < $TT_FILE_TEMP_VERSION) {
295        warn(<<EOF);
296
297The Template Toolkit requires that the File::Temp module (version $TT_FILE_TEMP_VERSION
298or later) first be installed.  This is used by the Template::Document
299class for storing compiled templates.  It is available from CPAN:
300
301    http://search.cpan.org/search?dist=File-Temp
302
303EOF
304    }
305}
306
307
308#------------------------------------------------------------------------
309# optional_stash_xs()
310#
311# Prompt for installation and default use of XS Stash.
312#------------------------------------------------------------------------
313
314sub optional_stash_xs {
315#    return if $TT_ACCEPT && (! $TT_XS_ENABLE || $TT_XS_ENABLE eq 'n');
316
317    message(<<EOF);
318
319
320Template::Stash::XS
321-------------------
322
323The Template::Stash module is a core part of the Template Toolkit,
324implementing the magic for accessing data using the dot notation.
325
326There is a high speed version, Template::Stash::XS, written in C.
327This makes the Template Toolkit run about twice as fast as when using
328the regular Template::Stash written in Perl.  If you've got a C
329compiler on your system then you can elect to have the XS Stash built.
330You can also specify that you want to use the XS Stash by default.
331
332Note that as of version 2.15 the XS Stash now supports access to tied
333hashes and arrays.
334
335See 'perldoc Template::Config' for further details.
336
337EOF
338
339    $TT_XS_ENABLE = (ttprompt('Do you want to build the XS Stash module?',
340                              $TT_XS_ENABLE) =~ /^y/i);
341
342    if ($TT_XS_ENABLE) {
343        $TT_XS_DEFAULT =
344            (ttprompt('Do you want to use the XS Stash by default?',
345                      $TT_XS_DEFAULT) =~ /^y/i);
346    }
347    else {
348        # If the XS stash is disabled, we cannot use it as the default stash.
349        $TT_XS_DEFAULT = 0;
350    }
351
352    # Actually, we would have to fix 'Config.pm' only if the XS stash is
353    # disabled. But this way, we are sure the correct module is used.
354        fix_file(catfile('lib','Template','Config.pm'),
355                 '$STASH',
356                 $TT_XS_DEFAULT ? 'Template::Stash::XS' : 'Template::Stash');
357}
358
359
360
361
362
363#--------------------------------------------------------------------
364# write_defaults()
365#
366# write configuration defaults to file
367#--------------------------------------------------------------------
368
369sub write_defaults {
370    open(FP, "> $DEFAULTS_FILE") || die "$DEFAULTS_FILE: $!\n";
371    my ( $ttxs_enable, $ttxs_default )
372            = map { $_ ? 'y' : 'n' }
373            ( $TT_XS_ENABLE, $TT_XS_DEFAULT );
374    print FP <<EOF;
375\$TT_XS_ENABLE     = '$ttxs_enable';
376\$TT_XS_DEFAULT    = '$ttxs_default';
377\$TT_ACCEPT        = '$TT_ACCEPT';
378\$TT_QUIET         = '$TT_QUIET';
3791;
380EOF
381    close(FP);
382}
383
384
385
386
387#------------------------------------------------------------------------
388# fix_file($file, $find, $fix)
389#
390# Fixes a variable definition in a file.  e.g.
391# fix_file('templates/splash/config', 'images', '/tt2/splash')
392#------------------------------------------------------------------------
393
394sub fix_file {
395    my ($file, $find, $fix) = @_;
396    local *FP;
397    local $/ = undef;
398
399    $find = quotemeta($find);
400
401    open(FP, "< $file") || die "$file: $!\n";
402    my $text = <FP>;
403    close(FP);
404
405    ($text =~ s/^(\s*${find}\s*=\s*)'.*?'/$1'$fix'/m)
406        || die "$find not found in $file\n";
407
408    open(FP, "> $file") || die "$file: $!\n";
409    print FP $text;
410    close(FP);
411}
412
413
414#------------------------------------------------------------------------
415# find_program($path, $prog)
416#
417# Find a program, $prog, by traversing the given directory path, $path.
418# Returns full path if the program is found.
419#
420# Written by Craig Barratt, Richard Tietjen add fixes for Win32.
421#
422# abw changed name from studly caps findProgram() to find_program() :-)
423#------------------------------------------------------------------------
424
425sub find_program {
426    my($path, $prog) = @_;
427#     my $sep = $WIN32 ? qr/;/ : qr/:/;
428#     foreach my $dir ( split($sep, $path) ) {
429    foreach my $dir ( split($Config{path_sep}, $path) ) {
430        my $file = File::Spec->catfile($dir, $prog);
431        if ( !$WIN32 ) {
432            return $file if ( -x $file );
433        } else {
434            # Windows executables end in .xxx, exe precedes .bat and .cmd
435            foreach my $dx ( qw/exe bat cmd/ ) {
436                return "$file.$dx" if ( -x "$file.$dx" );
437            }
438        }
439    }
440}
441
442
443#------------------------------------------------------------------------
444# message($text)
445#
446# Print message unless quiet mode.
447#------------------------------------------------------------------------
448
449sub message {
450    return if $TT_QUIET;
451    print @_;
452}
453
454
455#------------------------------------------------------------------------
456# ttprompt($message, $default)
457#------------------------------------------------------------------------
458
459sub ttprompt {
460    my ($msg, $def)=@_;
461    my $ISA_TTY = -t STDIN && (-t STDOUT || !(-f STDOUT || -c STDOUT)) ; # Pipe?
462    my $dispdef = defined $def ? "[$def] " : " ";
463    $def = defined $def ? $def : "";
464    my $ans = '';
465    local $|=1;
466    print "$msg $dispdef" unless $TT_QUIET;
467    if ($TT_ACCEPT || ! $ISA_TTY) {
468        print "$def\n" unless $TT_QUIET;
469    }
470    else {
471        chomp($ans = <STDIN>);
472    }
473    return ($ans ne '') ? $ans : $def;
474}
475
476
477#------------------------------------------------------------------------
478# yep($text)
479#------------------------------------------------------------------------
480
481sub yep {
482    return if $TT_QUIET;
483    print '[X] ', shift, "\n";
484}
485
486
487#------------------------------------------------------------------------
488# nope($text)
489#------------------------------------------------------------------------
490sub nope {
491    return if $TT_QUIET;
492    print '[ ] ', shift, "\n";
493}
494