Foswiki on GitHub is open for business! Next release meeting: Monday October 13, 1300Z

internal package Foswiki::Configure::Package

See PublishedAPI for packages intended to be used by Plugin and Contrib authors, or browse all packages.
See also Developing plugins, Developer's Bible, Technical Overview

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>
Topic revision: r1 - 19 Apr 2011, ProjectContributor
 
This site is powered by FoswikiCopyright © by the contributing authors. All material on this site is the property of the contributing authors.
Ideas, requests, problems regarding Foswiki? Send feedback