internal package
Foswiki::Configure::Package
Objects of this class represent an installed or installable
Foswiki Extension.
To the caller, the Package object carries the manifest of the package,
and provides methods for loading the manifest from an extension installer,
and for backing up, installing or removing an Extension from the Foswiki
installation.
The internal storage of the manifest is as a hash. The hash is populated
as two possible views:
- File View - lists the attributes of each file in the package
- Attachment View - list the files to be attached to each topic.
Pictorially,
- MANIFEST
-
{path/file.name}
Distributed filename root is Foswiki root.
-
{ci}
- Flag specifying if file should be checked into the RCS system
-
{perms}
- File permissions in Linux octal string format
-
{md5}
- MD5 checksum of file - optional
-
{web}
- Web/Subweb name if topic or attachment
-
{topic}
- Topic name if topic or attachment
-
{attach}
- Attachment name if attachment
-
{ATTACH}
-
{Web/Subweb/Topic}
- {AttachmentName} = Filename of the attachment.
ClassMethod
new($root, $pkgname, $type, $session)
-
$root
- The root of the Foswiki installation - used for file operations
-
$pkgname
- The name of the the package.
- $type - The type of package represented by this objct. Supported types include:
- Plugin - A Foswiki Extension of type Plugin - Defined in Extension/_extension_.pm
- Skin - A Foswiki Skin
- Contrib - A Foswiki Contribution or AddOn. Defined in Contrib/_extension_.pm
- Core - (future) a packaged core installation.
-
$session
(optional) - a Foswiki object (e.g. $Foswiki::Plugins::SESSION
)
Required for installer methods - used for checkin operations
-
$options
- A hash of options for the installation
{
EXPANDED => 0/1 Specify that archive file has already been expanded
USELOCAL => 0/1 If local versions of _installer or archives are found, use them instead of download.
SHELL => 0/1 Specify if executed from shell - default is to generate html markup in messages.
NODEPS => 0/1 Set if dependencies should not be installed. Default is to always install Foswiki dependencies.
(CPAN and external dependencies are not handled by this module.)
SIMULATE => 0/1 Set to 1 if actions should be simulated - no file system modifications other than temporary files.
CONTINUE => 0/1 If set to 1, the installation will continue even if errors are encountered. (future)
}
ObjectMethod
finish()
Clean up the object, releasing any memory stored in it.
ObjectMethod
repository()
Get or set the respository associated with the object.
ObjectMethod
pkgname([$name])
-
$name
- optional, change the package name in the object
Get/set the web name associated with the object.
ObjectMethod
errors()
Return any errors encountered duriung the installation of this object
and those returned by any dependencies.
ObjectMethod
logfile( $this, $options )
Get or set the logfile used to store the results of the requested operations.
Options hash can include:
filename => Override of generated name including path
action => Action - Install, Remove etc.
path => Override the default logging path
Default name:
NameOfPackage-[action]-yyyymmdd-hhmmss.log
ObjectMethod
log( $this, $string )
Write the $string to the logfile.
ObjectMethod
install()
Perform a full installation of the package, including all dependencies
and any required downloads from the repository.
A backup is taken before any changes are made to the file system.
Missing directories are created as required. The files are mapped into non-standard
locations by the mapTarget utility routine. If a file is read-only, it is temporarily
overridden and the mode of the file is restored after the move.
The $session is a Foswiki session used for Topic checkin when required. The session - while
optional, must be set prior to running the install method.
Files are "checked in" by creating a Topic Meta object and using the Foswiki Meta API to
save the topic.
- If the file is new, with no history, it is simply copied,
- If the file exists and has rcs history ( *,v file exists), it is always checked in
- If the file exists without history, the Manifest "CI" flag is followed
-
%options
(optional) options to override behavior - primarily for unit tests.
- =DIR => directory where installer package is found
-
USELOCAL => 1
Use local archives if found (Used by shell installations)
-
EXPANDED => 1
Archive file has already been expanded - preventing any downloads - for unit tests
-
NODEPS => 1
Don't install any dependents
-
SIMULATE => 1
Don't actually install, just report expected results. No logs are written.
ObjectMethod
install()
Install files listed in the manifest.
_installAttachments ()
Install the attachments associated with a topic. Used when
attachments or the owning topic have revision data to maintain.
Otherwise the attachments are just copied.
_moveFile ()
Make the path as required and move or copy the file into the target location
ObjectMethod
createBackup ()
Create a backup of the extension by copying the files into the
working/configure/backup/
directory. If system archive
tools are available, then the directory will be compressed
into a backup file.
ObjectMethod
setPermissions ()
Check each installed file against the manifest. Apply the
permissions to the file.
listFiles ( $installed )
Return the sorted list of files in the package.
If $installed is true, return the list of files that are actually installed
including rcs files.
ObjectMethod
listPlugins ()
List the plugin modules provided by this extension.
uninstall ( $simulate )
Remove each file identified by the manifest. Also remove
any rcs "...,v" files if they exist. Note that directories
are NOT removed unless they are empty.
Pre and Post un-install exits are run.
Returns the list of files that were removed. If simulate is set to
true, no files are uninstalled, but the list of files that would
have been removed is returned.
loadInstaller ([$options])
This routine looks for the $extension_installer or
$extension_installer.pl file and extracts the manifest,
dependencies and pre/post Exit routines from the installer.
The local search path is:
- Directory passed as parameter, or root of installation
- This directory is also examined for the .pl version of the _installer
- The
working/Configure/download
directory (recently downloaded)
- The
working/Configure/pkgdata
directory (previously installed)
If the installer is not found and a repository is provided, the
installer file will be retrieved from the repository.
The manifest and dependencies are parsed and loaded into their
respective hashes. The pre and post routines are eval'd and
installed as methods for this object.
-
%options
(optional) options to override behavior - primarily for unit tests.
- =DIR => directory where installer package is found
-
USELOCAL => 1
Use local archives if found (Used by shell installations)
-
EXPANDED => 1
Archive file has already been expanded - preventing any downloads - for unit tests
Returns:
- Warning text if no fatal errors occurred
- Error messages if load failed.
ObjectMethod
loadExits ()
Evaluate the pre and post install / uninstall routines extracted from
the package file.
ObjectMethod
deleteExits ()
Delete the pre and post install / uninstall routines from the namespace
ObjectMethod
Manifest ()
Return the manifest in printable format
_parseManifest ( $line )
Parse the manifest line into the manifest hash.
->{filename}->{ci} Flag if file should be "checked in"
->{filename}->{perms} File permissions
->{filename}->{MD5} MD5 of file (if available)
parseDependency ( \%DEPENDENCY, $)
Parse the manifest line into the manifest hash.
ObjectMethod
checkDependencies ()
Checks the dependencies listed for this module. Returns two "reports";
Installed dependencies and Missing dependencies. It also returns a
list of Foswiki package names that might be installed and a list of the
CPAN modules that could be installed.
ObjectMethod
installDependencies ()
Installs the dependencies listed for this module. Returns the details
of the installation.
ObjectMethod
_fetchFile ( $this, $ext )
Internal function to fetch a file from a repository. It uses the repository hash
set for the object:
my $repository = {
name => 'Foswiki',
data => 'http://foswiki.org/Extensions/',
pub => 'http://foswiki.org/pub/Extensions/' };
<verbatim>
$ext is the filetype to be fetched - .tgz, .zip, .md5, _installer.
The function returns the file location & name, along with a message if any.
=cut
sub _fetchFile {
my $this = shift;
my $ext = shift;
my $arf =
$this->{_repository}->{pub}
. $this->{_pkgname} . '/'
. $this->{_pkgname}
. $ext;
if ( defined( $this->{_repository}->{user} ) ) {
$arf .= '?username=' . $this->{_repository}->{user};
if ( defined( $this->{_repository}->{pass} ) ) {
$arf .= ';password=' . $this->{_repository}->{pass};
}
}
my $ar;
my $feedback;
my $response = Foswiki::Configure::Package::_getUrl($arf);
if ( !$response->is_error() ) {
eval { $ar = $response->content(); };
}
else {
$@ = $response->message();
}
if ($@) {
$feedback .= <<HERE;
I can't download $arf because of the following error:
$@
HERE
return $feedback;
}
if ( !defined($ar) ) {
$feedback .= <<HERE;
No content. Extension may not have been packaged correctly.
HERE
return $feedback;
}
# Strip HTTP headers if necessary
$ar =~ s/^HTTP(.*?)\r\n\r\n//sm;
# Save it somewhere it will be cleaned up
my ( $fh, $tmpfilename ) =
File::Temp::tempfile( SUFFIX => $ext, UNLINK => 1 );
binmode($fh);
print $fh $ar;
$fh->close();
return ( '', $tmpfilename );
}
sub _getUrl {
my ($url) = @_;
require Foswiki::Net;
my $tn = new Foswiki::Net();
my $response = $tn->getExternalResource($url);
$tn->finish();
return $response;
}
1;
__END__
Foswiki - The Free and Open Source Wiki, http://foswiki.org/
Copyright (C) 2008-2010 Foswiki Contributors. Foswiki Contributors
are listed in the AUTHORS file in the root of this distribution.
NOTE: Please extend that file, not this notice.
Additional copyrights apply to some or all of the code in this
file as follows:
Copyright (C) 2001-2007 Peter Thoeny, peter@thoeny.org
and TWiki Contributors. All Rights Reserved.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. For
more details read LICENSE in the root of this distribution.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
As per the GPL, removal of this notice is prohibited.
</verbatim>