package votorola::b::GWT; # Copyright 2010, 2012-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 EXPORTS =over 4 =cut BEGIN { use Exporter (); our @ISA; @ISA = qw( Exporter ); our @EXPORT_OK; @EXPORT_OK = qw( codeserver compile compile_time_library_jar_list devmode SDK_dir runtime_library_jar_list version ); } 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; my $version = version(); # my $expected_version = '2.8.0'; # $expected_version gt $version and die "Expecting at least version '$expected_version', found '$version'."; my $expected_version = '2.8.0+mca.1'; # get it from http://reluk.ca/project/_/gwt/release/ if( $expected_version ne $version ) { die "Expecting GWT version '$expected_version', found '$version'. " . "You may need an upgrade from http://reluk.ca/project/_/gwt/release/. Died"; } } =pod =item B() Call the CodeServer for "super" development mode, per script gwt-codeserver. =cut sub codeserver() { use votorola::b::Build qw( %option ); use votorola::b::Console qw( print_score $verbosity ); use votorola::b::Function qw( system_exit_decode ); my $sdk_dir = SDK_dir(); my $command; $command = join_clean( ' ', votorola::b::Java::home_dir() . '/bin/java', _common_Java_options(), '-classpath ' . _classpath() . ":$sdk_dir/gwt-codeserver.jar", 'com.google.gwt.dev.codeserver.CodeServer' ); if( defined $option{'help'} ) { $command = join_clean( ' ', $command, '-help' ); } else { $command = join_clean( ' ', $command, custom_codeserver_options(), @ARGV ); } # else call it without any options or arguments in order to show options if( $verbosity ) { print "$command\n"; print_score( undef, '^' ); } system $command; $? != 0 and exit system_exit_decode( $? ); } =pod =item B() Compiles all GWT modules for production-mode deployment. =cut sub compile() { use votorola::b::Build qw( %option out_dir ); use votorola::b::Console qw( print_score $verbosity ); use votorola::b::Function qw( join_clean system_exit_decode ); my $modules = $option{'module'}; if( !defined $modules ) { $modules = join_clean( ' ', 'votorola.s.gwt.stage.StageIn', 'votorola.s.gwt.mediawiki.MediaWikiIn', 'votorola.s.gwt.pollwiki.PollwikiIn', 'votorola.s.gwt.scene.SceneIn', 'votorola.s.gwt.wic.CountIn', 'votorola.s.gwt.wic.DIn' ); # Changing these? Change also in a/web/context/, and maybe also change the "In" pattern # in votorola::b::Build::build__target_doc. } my $command = join_clean( ' ', votorola::b::Java::home_dir() . '/bin/java', _common_Java_options(), custom_compiler_java_options(), '-classpath ' . _classpath(), 'com.google.gwt.dev.Compiler', # for all options > java -classpath GWT_SDK_DIR/gwt-dev.jar com.google.gwt.dev.Compiler _common_GWT_options(), '-strict', '-war ' . out_dir() . '/votorola/a/web/context', custom_compiler_options(), $modules ); print votorola::b::Build::call_stack_indentation() . "(compile\n"; if( $verbosity ) { print "\n$command\n"; print_score( undef, '^' ); } system $command; $? != 0 and exit system_exit_decode( $? ); } =pod =item B() The list of all GWT library jars that are needed at compile time and are external to Votorola, meaning outside of its code repository. The list is cached. It should be appended to the Java::compile_time_library_jar_list(). =cut sub compile_time_library_jar_list() { our @_compile_time_library_jar_list; # cached if( !@_compile_time_library_jar_list ) # then lazily create it { my @list = (); push( @list, SDK_dir() . '/gwt-user.jar'); # for client-side GWT source push( @list, SDK_dir() . '/validation-api-1.0.0.GA.jar'); # dependency of gwt-user.jar as of GWT 2.3 http://groups.google.com/group/google-web-toolkit/t/0819c7c83eb224d8 push( @list, SDK_dir() . '/validation-api-1.0.0.GA-sources.jar'); @_compile_time_library_jar_list = @list; } return @_compile_time_library_jar_list; } =pod =item B() Serves one or more GWT modules in development mode, per script gwt-devmode. =cut sub devmode() { use votorola::b::Build qw( %option ); use votorola::b::Console qw( print_score $verbosity ); use votorola::b::Function qw( system_exit_decode ); my $modules = $option{'module'}; defined $modules or $modules = 'votorola.s.gwt.pollwiki.PollwikiIn'; # not sure why, but that alone appears to suffice for running almost any stage module my $command = join_clean( ' ', votorola::b::Java::home_dir() . '/bin/java', _common_Java_options(), custom_devmode_java_options(), '-classpath ' . _classpath(), 'com.google.gwt.dev.DevMode', # for all options > java -classpath GWT_SDK_DIR/gwt-dev.jar com.google.gwt.dev.DevMode _common_GWT_options(), '-noserver', # no Jetty needed for HTTP files, will run our own Tomcat '-port 8080', custom_devmode_options(), $modules ); if( $verbosity ) { print "$command\n"; print_score( undef, '^' ); } system $command; $? != 0 and exit system_exit_decode( $? ); } =pod =item B() The list of all GWT library jars that are needed at runtime and are external to Votorola, meaning outside of its code repository. =cut sub runtime_library_jar_list() { our @_runtime_library_jar_list; # cached if( !@_runtime_library_jar_list ) # then lazily create it { my @list = (); push( @list, SDK_dir() . '/gwt-servlet.jar'); # for GWT RPC # we serve JSONP instead of RPC, but we need this for sake of RegExp class (in # use of GWTX.DEV_MODE_LOCATION_PATTERN) and such like on the server @_runtime_library_jar_list = @list; } return @_runtime_library_jar_list; } =pod =back =head1 PRIVATE =over 4 =cut ##### P r i v a t e ###################################################################### =pod =item B<_classpath>() Returns the common portion of the classpath for both compile() and devmode(). =cut sub _classpath() { use votorola::b::Build qw( build_cache_root ); use votorola::b::Java qw( compile_class_outdir ); my $sdk_dir = SDK_dir(); my $classpath = '.'; # $classpath .= ':/home/mike/code/gwt/x-release/repo/user/src'; # TEST $classpath .= ':' . compile_class_outdir(); for my $path( votorola::b::Java::compile_time_library_jar_list() ) { next if $path eq 'votorola/g/web/google-gson.jar'; # codeserver depends on (and pulls in) a newer version; don't clobber it next if $path eq 'votorola/g/web/servlet-api.jar'; # codeserver + embedded servlet container depend on (and pull in) a newer version; don't clobber it $classpath .= ':'; $classpath .= $path; } $classpath .= ":$sdk_dir/gwt-user.jar:$sdk_dir/gwt-dev.jar"; # Last in order to "make sure lib-gwt-svg.jar appears before the GWT SDK." # See http://www.vectomatic.org/lib-gwt-svg/getting-started return $classpath; } =pod =item B<_common_GWT_options>() ret @options Returns GWT options common to both compile() and devmode(). =cut sub _common_GWT_options() { return ( '-extra ' . _extra_outdir(), '-logLevel WARN', # ERROR, WARN, INFO, TRACE, DEBUG, SPAM, ALL '-war ' . out_dir() . '/votorola/a/web/context' ) } =pod =item B<_common_Java_options>() ret @options Returns Java options common to both compile() and devmode(). =cut sub _common_Java_options() { return ( # '-Xmx512M', ## MCA moved to custom_*_java_options in config file GWT_config.pl '-Dgwt.persistentunitcachedir=' . _extra_outdir() # per http://code.google.com/p/google-web-toolkit/issues/detail?id=6802 # else dir gwt-unitCache is output ); } =pod =item B<_extra_outdir>() The directory to which extra files are output, per GWT compiler -extra. =cut sub _extra_outdir() { use votorola::b::Build qw( build_cache_root ); return build_cache_root() . '/votorola/GWT-extra-out'; } =pod =back =cut 1;