App-Framework-Lite

 view release on metacpan or  search on metacpan

lib/App/Framework/Lite.pm  view on Meta::CPAN

  }


=head1 DESCRIPTION

App::Framework::Lite is a framework for quickly developing application scripts, where the majority of the mundane script setup,
documentation jobs are performed by the framework (under direction from simple text definitions stored in the script). This leaves 
the developer to concentrate on the main job of implementing the application.

The module also provides the facility of embedding itself into a copy of the original script, creating a self-contained stand-alone
script (for further details see L</EMBEDDING>).

Note that this module provides a subset of the the facilities provided by L<App::Framework>, In particular, it provides the L<App::Framework::Features:Args>,   
L<App::Framework::Features:Options>, and L<App::Framework::Features:Data> features.

To jump straight in to developing applications, please see L<App::Framework::Lite::GetStarted>.

=head2 Capabilities

The application framework provides the following capabilities: 

lib/App/Framework/Lite.pm  view on Meta::CPAN


	* $progpath
	* $progpath/lib
	
i.e. The directory that the script resides in, and a sub-directory 'lib' will be searched for application-specific modules.

Note that this is the path also used when the framework loads in the core personality, and any optional extensions.

	

=head2 EMBEDDING

A script may be developed and debugged using the App::Framework::Lite module installed on a system, and then turned into a standalone Perl
script by embedding the App::Framework::Lite module into the script file. Also, a developer may choose to also embed any user library modules
related to this script (or may just deliver them in their dubdirectory along with the standalone script).

=head3 Embedding Procedure

When a script is using the App::Framework::Lite module, some developer command line options are automatically added to the script. The developer
uses these options in the embedding process:

lib/App/Framework/Lite.pm  view on Meta::CPAN

#============================================================================================
our @ISA ; 

#============================================================================================
# GLOBALS
#============================================================================================

my $class_debug ;

# default to state that the module is embedded (overwritten inside BEGIN block)
my $EMBEDDED = 0 ;

# Maximum line length when embedding (e.g. ensures Clearcase doesn't think file is binary!)
my $MAX_LINE_LEN = 5000 ;

# Keep track of import info
my $import_args ;

# Run error action
our $ON_ERROR_DEFAULT = 'fatal' ;

lib/App/Framework/Lite.pm  view on Meta::CPAN

	['dryrun|"norun"',	'Dry run', 			'Do not execute anything that would alter the file system, just show the commands that would have executed'],
	['h|"help"',		'Print help', 		'Show brief help message then exit'],
	['man',				'Full documentation', 'Show full man page then exit' ],
	['man-dev',			'Full developer\'s documentation', 'Show full man page for the application developer then exit' ],
	['log=s',			'Log file', 		'Specify a log file', ],
	['dev:pod',			'Output full pod', 	'Show full man page as pod then exit' ],
	['dev:dbg-data',		'Debug option: Show __DATA__', 				'Show __DATA__ definition in script then exit' ],
	['dev:dbg-data-array',	'Debug option: Show all __DATA__ items', 	'Show all processed __DATA__ items then exit' ],
	['dev:alf-info',	'Module information', 	'Display information about the App::Framework::Lite module then exit' ],
	['dev:alf-debug=i',	 'Debug App::Framework::Lite', 	'Set the debug level value of the App::Framework::Lite module', ],
#@NO-EMBED BEGIN
	['dev:alf-embed=s',		'Embed module', 	'Embed the App::Framework::Lite module into script then exit. Specify the filename of the new script.' ],
	['dev:alf-embed-lib=i',	'Embed libraries', 	'(Only used when embedding). Embed user modules as well as the App::Framework::Lite module.', 1 ],
	['dev:alf-compress=i',	'Compress embedded', 	'(Only used when embedding). Compress the embedded modules.', 1 ],
#@NO-EMBED END
	) ;

our @USED = (
	'Carp',
	'Cwd',
	'Getopt::Long qw(:config no_ignore_case)',
	'Pod::Usage',
	'File::Basename',
	'File::Path',
	'File::Temp',

lib/App/Framework/Lite.pm  view on Meta::CPAN


our @OPT_MOD = (
	'File::Which',
) ;
our %AVAILABLE_MOD ;


#============================================================================================
BEGIN {

#@NO-EMBED BEGIN
	# Clear flag for non-embedded
	$EMBEDDED = 1 ;
#@NO-EMBED END

	## Get caller information
	my ($package, $filename, $line, $subr, $has_args, $wantarray) = caller(0) ;

	## Add a couple of useful function calls into the caller namespace
	{
		no warnings 'redefine';
		no strict 'refs';

		foreach my $fn (qw/go/)	

lib/App/Framework/Lite.pm  view on Meta::CPAN

	if ($opts{'dbg-data-array'})
	{
		$this->_show_data_array() ;
		$this->exit(0) ;
	}

	if ($opts{'alf-info'})
	{
		print "App::Framework::Lite info\n" ;
		print "  Version:  $VERSION\n" ;
		print "  Embedded: " . ($EMBEDDED ? "yes" : "no") . "\n" ;
		$this->exit(0) ;
	}

#@NO-EMBED BEGIN
	if ($opts{'alf-embed'})
	{
		my $src = $this->{'filename'} ;
#		my $dest = $this->{'progpath'} . '/' . "alf-" . $this->{'progname'} . $this->{'progext'} ;
		my $dest = $opts{'alf-embed'} ;
		my %libs = $this->embed($src, $dest, $opts{'alf-compress'}, $opts{'alf-embed-lib'}) ;
		print "Embedded App::Framework::Lite into $src. Stand-alone script saved as $dest.\n" ;
		print "Embedded the following library modules:\n" ;
		foreach my $mod (sort {$libs{$a}{'order'} <=> $libs{$b}{'order'} } keys %libs)
		{
			print "    $mod\n" ;
		}
		
		print "Have a nice life.\n" ;
		$this->exit(0) ;
	}
#@NO-EMBED END

	if ($opts{'log'})
	{
		$this->{logfile} = $opts{'log'} ;
	}

}


#----------------------------------------------------------------------------

lib/App/Framework/Lite.pm  view on Meta::CPAN

			last if $found ;
		}
	}

#print "find_lib() = $found\n" ;

	return $found ;
}


#@NO-EMBED BEGIN

#----------------------------------------------------------------------------
sub _module_to_embed
{
	my $this = shift @_ ;
	my ($module, $file, $embed_libs) = @_ ;
	
	my $embed_it = 0 ;

	## Always embed this module

lib/App/Framework/Lite.pm  view on Meta::CPAN

	my $strict = "";
	my $line ;
	while(defined($line = <$in_fh>))
	{
		chomp $line ;

print "LINE: $line\n" if $this->{'debug'};

		if ($line =~ /^__DATA__/)
		{
			print $out_fh <<EMBED_START;
$perl_line
##################################################################################
# Start of embedded modules - embedded by App::Framework::Lite
#
# Your original script is now at the end of the file.
#
##################################################################################
#
$strict
EMBED_START
			
			# Handle any other embedded modules
			foreach my $mod (sort {$libs{$a}{'order'} <=> $libs{$b}{'order'} } keys %libs)
			{
				my $module_str = $libs{$mod}{'content'} ;
				
				print $out_fh "\n## EMBEDDED $mod ##\n" ;
				print $out_fh "$module_str\n" ;
				print $out_fh "\## EMBEDDED $mod - END ##\n" ;
			}
			
			print $out_fh <<EMBED_END;
#
##################################################################################
# End of embedded modules - embedded by App::Framework::Lite
##################################################################################
package main;

EMBED_END

#			print $out_fh "\n$line\n" ;
			push @main, "\n$line\n" ;
		}
		else
		{
			if (!$perl_line)
			{
				# find first line (if specifed)
				if ($line =~ /^#!/)

lib/App/Framework/Lite.pm  view on Meta::CPAN

	
	# output script body
	foreach my $line (@main)
	{
		print $out_fh "$line" ;
	}	
	close $out_fh ;	
	
	return %libs ;
}
#@NO-EMBED END


#============================================================================================
# PRIVATE
#============================================================================================

#@NO-EMBED BEGIN

#---------------------------------------------------------------------
# Squash module down to a few lines of text
sub _module_str
{
	my $this = shift ;
	my ($module, $compress, $libs_href, $embed_libs) = @_ ;
	
	my $module_str = "" ;

lib/App/Framework/Lite.pm  view on Meta::CPAN

	
	while(defined($line = <$in_fh>))
	{
		chomp $line ;

print " : LINE: $line\n" if $this->{'debug'};
print " (varinit=$varinit, pod=$pod)\n" if $this->{'debug'};

		next if $complete ;

		if ($line =~ /\@NO\-EMBED (\w+)/)
		{
			if ($1 eq 'BEGIN')
			{
				$no_embed = 1 ;
			}
			else
			{
				$no_embed = 0 ;
			}
			next ;

lib/App/Framework/Lite.pm  view on Meta::CPAN

				$varsdef .= "$var " ;
				$varsdef .= "\n" if $comment || $asis ;

	print " + + add var: $var\n" if $this->{'debug'};
			}
		}
		
		## Special case for App::Framework::Lite
		
		# Set embedded flag
		$line =~ s/\$EMBEDDED = 0/\$EMBEDDED = 1/ ;

		}
		
		## ensure we're not at the line limit
		my $line_len = length $line ;
		if ($current_len + $line_len >= $MAX_LINE_LEN)
		{
			$module_str .= "\n" ;
			$current_len = 0 ;
		}

lib/App/Framework/Lite.pm  view on Meta::CPAN

		$href = {
			'order'		=> $order,
			'content'	=> "",
		} ;
		$libs_href->{$module} = $href ;
	}

	return $href ;
}

#@NO-EMBED END


#---------------------------------------------------------------------
sub _setup_modules
{
	my $this = shift ;

	## Set up optional routines

	# Attempt to load Debug object



( run in 1.370 second using v1.01-cache-2.11-cpan-71847e10f99 )