SWF-NeedsRecompile

 view release on metacpan or  search on metacpan

lib/SWF/NeedsRecompile.pm  view on Meta::CPAN

package SWF::NeedsRecompile;

use warnings;
use strict;
use 5.008;    # tested only on 5.8.6+, but *should* work on older perls
use Carp;
use English qw(-no_match_vars);
use File::Spec;
use File::Slurp qw();
use Regexp::Common qw(comment);
use File::HomeDir;
use List::MoreUtils qw(any);

our $VERSION = '1.06';

use base qw(Exporter);
our @EXPORT_OK = qw(
   check_files
   as_classpath
   flash_prefs_path
   flash_config_path
);

my $cached_as_classpath;

my $verbosity = 0;
__PACKAGE__->set_verbosity($ENV{SWFCOMPILE_VERBOSITY});

my %os_paths = (
   darwin => {
      pref => [File::Spec->catfile(File::HomeDir->my_home, 'Library', 'Preferences', 'Flash 7 Preferences')],
      conf => [File::Spec->catfile(File::HomeDir->my_home, 'Library', 'Application Support', 'Macromedia',
                                   'Flash MX 2004', 'en', 'Configuration')],
   },
   # TODO: add more entries for "MSWin32", etc
);
# These are mostly Flash 6 component classes
my %exceptions = map { $_ => 1 } qw(
   DataProviderClass
   FScrollSelectListClass
   FSelectableItemClass
   FSelectableListClass
   FStyleFormat
   FUIComponentClass
   Tween
);

sub _get_os_paths    # FOR TESTING ONLY!!!
{
   return \%os_paths;
}

=for stopwords Actionscript Classpath MTASC MX SWF .swf .fla timestamp wildcards UCS2 Dolan Macromedia

=head1 NAME 

SWF::NeedsRecompile - Tests if any SWF or FLA file dependencies have changed

=head1 LICENSE

Copyright 2002-2006 Clotho Advanced Media, Inc.,
L<http://www.clotho.com/>

Copyright 2007-2008 Chris Dolan

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=head1 SYNOPSIS

    use SWF::NeedsRecompile qw(check_files);
    foreach my $file (check_files(<*.swf>)) {
       print "SWF needs recompilation: $file\n";
    }

=head1 DESCRIPTION

This module parses .fla and .as files and determines dependencies
recursively, via import and #include statements.  It then compares the
timestamps of all of the dependencies against the timestamp of the

lib/SWF/NeedsRecompile.pm  view on Meta::CPAN

   return @deps;
}

sub _get_instantiations
{
   my $checkfile         = shift;
   my $content_ref       = shift;
   my $fla_path_ref      = shift;
   my $imported_file_ref = shift;
   my $seen_ref          = shift;

   # Get a list of all classes defined in this file
   my @classes;
   my @class_matches = ${$content_ref} =~ m/c\0?l\0?a\0?s\0?s\0?(?:\s\0?)+((?:[^;\s\0]\0?)+)/gxms;
   for my $class_match (@class_matches)
   {
      $class_match =~ s/\0//gxms;
      push @classes, $class_match;
   }

   my @deps;
   my @matches = ${$content_ref} =~ m/n\0?e\0?w\0?(?:\s\0?)+((?:[\w.]\0?)+)[(]/gxms;
   foreach my $imp (@matches)
   {
      next if ($seen_ref->{$imp}++); # speedup
      # This is a hack.  Strip real Unicode down to ASCII
      $imp =~ s/\0//gxms;
      next if ($exceptions{$imp});
      _log(2, "instance $imp from $checkfile");
      next if ($imported_file_ref->{$imp . '.as'});
      # Is this class implemented in this very file?
      next if any { $_ eq $imp || m/[.]\Q$imp\E\z/xms } @classes;
      my $found = 0;
      foreach my $dir (@{$fla_path_ref}, as_classpath())
      {
         my $f = File::Spec->catdir(File::Spec->splitdir($dir), split m/[.]/xms, $imp);
         $f .= '.as';
         if (-f $f)
         {
            _log(2, "  instance $f from $checkfile");
            push @deps, $f;
            $found = 1;
            last;
         }
      }
      return [$imp] if (!$found);
   }
   return @deps;
}

=item $pkg->as_classpath()

Returns a list of Classpath directories specified globally in Flash.

=cut

sub as_classpath
{
   if (!$cached_as_classpath)
   {
      my $prefs_file = flash_prefs_path();
      if (!$prefs_file || ! -f $prefs_file)
      {
         #_log(2, 'Failed to locate the Flash prefs file');
         return q{.};
      }

      my $conf_dir = flash_config_path();
      for (File::Slurp::read_file($prefs_file))
      {
         if (m/<Package_Paths>(.*?)<\/Package_Paths>/xms)
         {
            my $cp = $1;
            my @dirs = split /;/xms, $cp;
            for (@dirs)
            {
               if (!$conf_dir)
               {
                  _log(2, "Failed to identify the UserConfig dir for '$_'");
               }
               else
               {
                  s/[$][(]UserConfig[)]/$conf_dir/xms;
               }
            }
            $cached_as_classpath = \@dirs;
            _log(2, "Classpath: @{$cached_as_classpath}");
            last;
         }
      }
   }
   return @{$cached_as_classpath};
}

=item $pkg->flash_prefs_path()

Returns the file name of the Flash preferences XML file.

=cut

sub flash_prefs_path
{
   return _get_path('pref');
}

=item $pkg->flash_config_path()

Returns the path where Flash stores all of its class prototypes.

=cut

sub flash_config_path
{
   return _get_path('conf');
}

=item $pkg->set_verbose($boolean)

=item $pkg->set_verbosity($number)

Changes the verbosity of the whole module.  Defaults to false.  Set to
a number higher than 1 to get very verbose output.

The C<SWFCOMPILE_VERBOSITY> environment variable sets this at module
load time.

The default is C<0> (silent), but we recommend setting verbosity to
C<1>, which emits error messages.  Setting to C<2> also emits
debugging messages.

=cut

sub set_verbose
{
   my $pkg           = shift;
   my $new_verbosity = shift;

   $pkg->set_verbosity($new_verbosity ? 1 : 0);
   return;
}

sub set_verbosity
{
   my $pkg           = shift;
   my $new_verbosity = shift;

   $verbosity = !$new_verbosity                     ? 0
              : $new_verbosity =~ m/\A (\d+) \z/xms ? $1
              :                                       1;
   return;
}

=item $pkg->get_verbosity()

Returns the current verbosity number.

=cut

sub get_verbosity
{
   my $pkg = shift;



( run in 1.683 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )