package votorola::b::Build; # Copyright 2008-2010, 2013, Michael Allan. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Votorola Software"), to deal in the Votorola Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Votorola Software, and to permit persons to whom the Votorola Software is furnished to do so, subject to the following conditions: The preceding copyright notice and this permission notice shall be included in all copies or substantial portions of the Votorola Software. THE VOTOROLA SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE VOTOROLA SOFTWARE OR THE USE OR OTHER DEALINGS IN THE VOTOROLA SOFTWARE. use strict; use warnings; =pod =head1 DESCRIPTION Build utilities and targets for Votorola. See the accompanying 'build' script for the description of the various targets. =cut BEGIN { use Exporter (); our @ISA; @ISA = qw( Exporter ); our @EXPORT_OK; @EXPORT_OK = qw( build_cache_root call_stack_indentation ensure_dir %option out_dir ); } our @EXPORT_OK; { use votorola::b::Config qw( do_fail config_basepath_from_package ); my $config_path = config_basepath_from_package(__PACKAGE__) . '.pl'; do $config_path or do_fail $config_path; } sub build__target_clean() { use File::Path qw( rmtree ); print call_stack_indentation() . "clean\n"; rmtree( build_cache_root() . '/votorola' ); rmtree( out_dir() ); } sub build__target_doc() { use File::Basename (); use votorola::b::FileSync qw( $from_dir sync_found $to_dir ); print call_stack_indentation() . "doc\n"; # Static copy of the source, lightly filtered # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $from_dir = 'votorola'; $to_dir = ensure_dir( out_dir() . '/votorola' ); File::Find::find( {follow_fast=>1, no_chdir=>1, wanted=>sub { m'/\.wh\.\.wh\.' and return; # skip AUFS whiteout file of my union mount (MCA) m'\.jar$' and return; # skip jar, those we need are deployed by build__target_x m'^votorola/a/web/context/votorola\.s\.[^/]+In$' and return; # skip placeholder for GWT build # Changing? Change also in votorola::b::GWT::compile m'^votorola/a/web/context/.+\(build\)$' and return; # ... for other built files m'^votorola/a/web/context/.+\(run\)$' and return; # ... and runtime files sync_found(); }}, $from_dir ); # CSS optimization # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if( defined $votorola::b::Build::option{'optimizeCSS'} ) { _optimize_css(); } # Static pages and resources for the web-based voter interface # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $to_dir = ensure_dir( out_dir() . '/votorola/a/web/context' ); sync_to_dir( "votorola/_/ie-png32-fix.js", $to_dir ); sync_to_dir( "votorola/_/brand/logo-16.png", $to_dir ); # Example configuration # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - copy_site_example( out_dir() . '/votorola/s/_/example' ); } sub build__target_javadoc() { use votorola::b::Java qw( compile javadoc ); print call_stack_indentation() . "javadoc\n"; compile(); javadoc(); } sub build__target_release() { print call_stack_indentation() . "release\n"; build__target_doc(); build__target_x(); build__target_xgwt(); build__target_javadoc(); } sub build__target_x() { use votorola::b::FileSync qw( $from_dir sync_found sync_to_dir sync_to_file $to_dir ); use votorola::b::Java qw( compile compile_class_outdir ); print call_stack_indentation() . "x\n"; # Votorola jar # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - my $out_dir_lib = ensure_dir( out_dir().'/votorola/a/web/context/WEB-INF/lib' ); my $jar_file = $out_dir_lib . '/votorola.jar'; compile(); $from_dir = '.'; # jar portions of source too, for runtime access $to_dir = compile_class_outdir(); File::Find::find( {follow_fast=>1, no_chdir=>1, wanted=>sub { my $f = $File::Find::name; # ./PATH filter: { $f =~ m'^\./\.hg' and return; # exclude repo internals $f =~ m'^\./votorola/b/mvn' and return; # exclude maven symlinks $f =~ m'^\.gwt\.xml$' and last; # include Google Web Toolkit modules, per Ant build that GWT ships with if( $f =~ m'^\./votorola/(?:.+/)?(?:WC|WP)_[A-Za-z0-9]+\.(.+)$' ) # web markup files { $1 eq '.java' and return; # exclude the Java code last; # include all others (mostly .html) } $f eq './votorola/a/locale' and last; $f =~ m'^\./votorola/a/locale/[^/]+\.properties$' and last; # include localized resource bundles $f eq './votorola/g/locale' and last; $f =~ m'^\./votorola/g/locale/[^/]+\.properties$' and last; # localized " return; # exclude all others } sync_found(); }}, $from_dir ); votorola::b::Java::jar( compile_class_outdir(), $jar_file ); # Runtime library jars # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - for my $jar( _runtime_library_jar_list() ) { my $to_jar = $out_dir_lib . '/' . File::Basename::basename( $jar ); sync_to_file( $jar, $to_jar ); my $txt = $jar; if( $txt =~ s!\.[^/.]+$!.txt! ) # foo.jar -> foo.txt { my $to_txt = $out_dir_lib . '/' . File::Basename::basename( $txt ); if( !-f $txt ) # no foo.txt { $txt = File::Basename::dirname( $jar ) . '/COPYING'; # for Apache licenced jars outside of revision control (GWT only, at present) } next if !-f $txt; # no licence at all sync_to_file( $txt, $to_txt ); } } # Command-line executables # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - _jar_executable( 'votorola.s.line', 'VOCount' ); _jar_executable( 'votorola.s.line', 'VODeliver' ); _jar_executable( 'votorola.s.mail', 'VOFaceMail', 'voface-mail' ); _jar_executable( 'votorola.s.line', 'VOHarvest' ); _jar_executable( 'votorola.s.line', 'VOLog' ); _jar_executable( 'votorola.s.line', 'VOMir' ); _jar_executable( 'votorola.s.line', 'VONop' ); _jar_executable( 'votorola.s.line', 'VOQProperties' ); _jar_executable( 'votorola.s.line', 'VOScript' ); _jar_executable( 'votorola.s.line', 'VOTer' ); _jar_executable( 'votorola.s.line', 'VOTrace' ); _jar_executable( 'org.webharvest', 'CommandLine', 'vowebharvest' ); } sub build__target_xgwt() { use votorola::b::GWT (); build__target_x(); print call_stack_indentation() . "xgwt\n"; votorola::b::GWT::compile(); } =pod =head1 EXPORTS =over 4 =cut # ---------------------------------------------------------------------------------------- =pod =item B() An indentation string reflecting the caller's call stack. =cut sub call_stack_indentation() { my $caller_bound = 1; # so far while( caller( $caller_bound )) { ++$caller_bound; } my $caller_count = $caller_bound - 1; --$caller_count; # subtract this call ++$caller_count; # correction (unknown reason) return ' ' x $caller_count; } =pod =item B( $dir ) ret $ Ensures that $dir exists. Returns $dir. =cut sub ensure_dir( $ ) { use File::Path qw( mkpath ); my $dir = shift; -d $dir or mkpath $dir or die $!; return $dir; } =pod =item %B