/common/libraries/plugin/pear/phing/tasks/ext/PearPackageTask.php
PHP | 500 lines | 256 code | 73 blank | 171 comment | 21 complexity | 2222dd9aaff3037bb9e098dbabe6cf8a MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1, LGPL-3.0, GPL-3.0, MIT
- <?php
- /*
- * $Id: PearPackageTask.php 843 2010-09-02 14:39:13Z mrook $
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * This software consists of voluntary contributions made by many individuals
- * and is licensed under the LGPL. For more information please see
- * <http://phing.info>.
- */
-
- require_once 'phing/tasks/system/MatchingTask.php';
- include_once 'phing/types/FileSet.php';
-
- /**
- * A task to create PEAR package.xml file.
- *
- * This class uses the PEAR_PackageFileMaintainer class to perform the work.
- *
- * This class is designed to be very flexible -- i.e. account for changes to the package.xml w/o
- * requiring changes to this class. We've accomplished this by having generic <option> and <mapping>
- * nested elements. All options are set using PEAR_PackageFileMaintainer::setOptions().
- *
- * The <option> tag is used to set a simple option value.
- * <code>
- * <option name="option_name" value="option_value"/>
- * or <option name="option_name">option_value</option>
- * </code>
- *
- * The <mapping> tag represents a complex data type. You can use nested <element> (and nested <element> with
- * <element> tags) to represent the full complexity of the structure. Bear in mind that what you are creating
- * will be mapped to an associative array that will be passed in via PEAR_PackageFileMaintainer::setOptions().
- * <code>
- * <mapping name="option_name">
- * <element key="key_name" value="key_val"/>
- * <element key="key_name" value="key_val"/>
- * </mapping>
- * </code>
- *
- * Here's an over-simple example of how this could be used:
- * <code>
- * <pearpkg name="phing" dir="${build.src.dir}" destFile="${build.base.dir}/package.xml">
- * <fileset>
- * <include name="**"/>
- * </fileset>
- * <option name="notes">Sample release notes here.</option>
- * <option name="description">Package description</option>
- * <option name="summary">Short description</option>
- * <option name="version" value="2.0.0b1"/>
- * <option name="state" value="beta"/>
- * <mapping name="maintainers">
- * <element>
- * <element key="handle" value="hlellelid"/>
- * <element key="name" value="Hans"/>
- * <element key="email" value="hans@xmpl.org"/>
- * <element key="role" value="lead"/>
- * </element>
- * </mapping>
- * </pearpkg>
- * </code>
- *
- * Look at the build.xml in the Phing base directory (assuming you have the full distro / CVS version of Phing) to
- * see a more complete example of how to call this script.
- *
- * @author Hans Lellelid <hans@xmpl.org>
- * @package phing.tasks.ext
- * @version $Id: PearPackageTask.php 843 2010-09-02 14:39:13Z mrook $
- */
- class PearPackageTask extends MatchingTask
- {
-
- /** */
- protected $package;
-
- /** Base directory for reading files. */
- protected $dir;
-
- /** Package file */
- private $packageFile;
-
- /** @var array FileSet[] */
- private $filesets = array();
-
- /** @var PEAR_PackageFileManager */
- protected $pkg;
-
- private $preparedOptions = array();
-
- /** @var array PearPkgOption[] */
- protected $options = array();
-
- /** Nested <mapping> (complex options) types. */
- protected $mappings = array();
-
- public function init()
- {
- include_once 'PEAR/PackageFileManager.php';
- if (! class_exists('PEAR_PackageFileManager'))
- {
- throw new BuildException("You must have installed PEAR_PackageFileManager in order to create a PEAR package.xml file.");
- }
- }
-
- /**
- * Sets PEAR package.xml options, based on class properties.
- * @return void
- */
- protected function setOptions()
- {
-
- // 1) first prepare/populate options
- $this->populateOptions();
-
- // 2) make any final adjustments (this could move into populateOptions() also)
-
-
- // default PEAR basedir would be the name of the package (e.g."phing")
- if (! isset($this->preparedOptions['baseinstalldir']))
- {
- $this->preparedOptions['baseinstalldir'] = $this->package;
- }
-
- // unless filelistgenerator has been overridden, we use Phing FileSet generator
- if (! isset($this->preparedOptions['filelistgenerator']))
- {
- if (empty($this->filesets))
- {
- throw new BuildException("You must use a <fileset> tag to specify the files to include in the package.xml");
- }
- $this->preparedOptions['filelistgenerator'] = 'Fileset';
- $this->preparedOptions['usergeneratordir'] = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'pearpackage';
- // Some PHING-specific options needed by our Fileset reader
- $this->preparedOptions['phing_project'] = $this->project;
- $this->preparedOptions['phing_filesets'] = $this->filesets;
- }
- elseif ($this->preparedOptions['filelistgeneragor'] != 'Fileset' && ! empty($this->filesets))
- {
- throw new BuildException("You cannot use <fileset> element if you have specified the \"filelistgenerator\" option.");
- }
-
- // 3) Set the options
-
-
- // No need for excessive validation here, since the PEAR class will do its own
- // validation & return errors
- $e = $this->pkg->setOptions($this->preparedOptions);
-
- if (PEAR :: isError($e))
- {
- throw new BuildException("Unable to set options.", new Exception($e->getMessage()));
- }
- }
-
- /**
- * Fixes the boolean in optional dependencies
- */
- private function fixDeps($deps)
- {
- foreach (array_keys($deps) as $dep)
- {
- if (isset($deps[$dep]['optional']) && $deps[$dep]['optional'])
- {
- $deps[$dep]['optional'] = "yes";
- }
- }
-
- return $deps;
- }
-
- /**
- * Adds the options that are set via attributes and the nested tags to the options array.
- */
- private function populateOptions()
- {
-
- // These values could be overridden if explicitly defined using nested tags
- $this->preparedOptions['package'] = $this->package;
- $this->preparedOptions['packagedirectory'] = $this->dir->getAbsolutePath();
-
- if ($this->packageFile !== null)
- {
- // create one w/ full path
- $f = new PhingFile($this->packageFile->getAbsolutePath());
- $this->preparedOptions['packagefile'] = $f->getName();
- // must end in trailing slash
- $this->preparedOptions['outputdirectory'] = $f->getParent() . DIRECTORY_SEPARATOR;
- $this->log("Creating package file: " . $f->__toString(), Project :: MSG_INFO);
- }
- else
- {
- $this->log("Creating [default] package.xml file in base directory.", Project :: MSG_INFO);
- }
-
- // converts option objects and mapping objects into
- // key => value options that can be passed to PEAR_PackageFileManager
-
-
- foreach ($this->options as $opt)
- {
- $this->preparedOptions[$opt->getName()] = $opt->getValue(); //no arrays yet. preg_split('/\s*,\s*/', $opt->getValue());
- }
-
- foreach ($this->mappings as $map)
- {
- $value = $map->getValue(); // getValue returns complex value
-
-
- if ($map->getName() == 'deps')
- {
- $value = $this->fixDeps($value);
- }
-
- $this->preparedOptions[$map->getName()] = $value;
- }
- }
-
- /**
- * Main entry point.
- * @return void
- */
- public function main()
- {
-
- if ($this->dir === null)
- {
- throw new BuildException("You must specify the \"dir\" attribute for PEAR package task.");
- }
-
- if ($this->package === null)
- {
- throw new BuildException("You must specify the \"name\" attribute for PEAR package task.");
- }
-
- $this->pkg = new PEAR_PackageFileManager();
-
- $this->setOptions();
-
- $e = $this->pkg->writePackageFile();
- if (PEAR :: isError($e))
- {
- throw new BuildException("Unable to write package file.", new Exception($e->getMessage()));
- }
-
- }
-
- /**
- * Used by the PEAR_PackageFileManager_PhingFileSet lister.
- * @return array FileSet[]
- */
- public function getFileSets()
- {
- return $this->filesets;
- }
-
- // -------------------------------
- // Set properties from XML
- // -------------------------------
-
-
- /**
- * Nested creator, creates a FileSet for this task
- *
- * @return FileSet The created fileset object
- */
- public function createFileSet()
- {
- $num = array_push($this->filesets, new FileSet());
- return $this->filesets[$num - 1];
- }
-
- /**
- * Set "package" property from XML.
- * @see setName()
- * @param string $v
- * @return void
- */
- public function setPackage($v)
- {
- $this->package = $v;
- }
-
- /**
- * Sets "dir" property from XML.
- * @param PhingFile $f
- * @return void
- */
- public function setDir(PhingFile $f)
- {
- $this->dir = $f;
- }
-
- /**
- * Sets "name" property from XML.
- * @param string $v
- * @return void
- */
- public function setName($v)
- {
- $this->package = $v;
- }
-
- /**
- * Sets the file to use for generated package.xml
- */
- public function setDestFile(PhingFile $f)
- {
- $this->packageFile = $f;
- }
-
- /**
- * Handles nested generic <option> elements.
- */
- public function createOption()
- {
- $o = new PearPkgOption();
- $this->options[] = $o;
- return $o;
- }
-
- /**
- * Handles nested generic <option> elements.
- */
- public function createMapping()
- {
- $o = new PearPkgMapping();
- $this->mappings[] = $o;
- return $o;
- }
- }
-
- /**
- * Generic option class is used for non-complex options.
- *
- * @package phing.tasks.ext
- */
- class PearPkgOption
- {
-
- private $name;
- private $value;
-
- public function setName($v)
- {
- $this->name = $v;
- }
-
- public function getName()
- {
- return $this->name;
- }
-
- public function setValue($v)
- {
- $this->value = $v;
- }
-
- public function getValue()
- {
- return $this->value;
- }
-
- public function addText($txt)
- {
- $this->value = trim($txt);
- }
-
- }
-
- /**
- * Handles complex options <mapping> elements which are hashes (assoc arrays).
- *
- * @package phing.tasks.ext
- */
- class PearPkgMapping
- {
-
- private $name;
- private $elements = array();
-
- public function setName($v)
- {
- $this->name = $v;
- }
-
- public function getName()
- {
- return $this->name;
- }
-
- public function createElement()
- {
- $e = new PearPkgMappingElement();
- $this->elements[] = $e;
- return $e;
- }
-
- public function getElements()
- {
- return $this->elements;
- }
-
- /**
- * Returns the PHP hash or array of hashes (etc.) that this mapping represents.
- * @return array
- */
- public function getValue()
- {
- $value = array();
- foreach ($this->getElements() as $el)
- {
- if ($el->getKey() !== null)
- {
- $value[$el->getKey()] = $el->getValue();
- }
- else
- {
- $value[] = $el->getValue();
- }
- }
- return $value;
- }
- }
-
- /**
- * Sub-element of <mapping>.
- *
- * @package phing.tasks.ext
- */
- class PearPkgMappingElement
- {
-
- private $key;
- private $value;
- private $elements = array();
-
- public function setKey($v)
- {
- $this->key = $v;
- }
-
- public function getKey()
- {
- return $this->key;
- }
-
- public function setValue($v)
- {
- $this->value = $v;
- }
-
- /**
- * Returns either the simple value or
- * the calculated value (array) of nested elements.
- * @return mixed
- */
- public function getValue()
- {
- if (! empty($this->elements))
- {
- $value = array();
- foreach ($this->elements as $el)
- {
- if ($el->getKey() !== null)
- {
- $value[$el->getKey()] = $el->getValue();
- }
- else
- {
- $value[] = $el->getValue();
- }
- }
- return $value;
- }
- else
- {
- return $this->value;
- }
- }
-
- /**
- * Handles nested <element> tags.
- */
- public function createElement()
- {
- $e = new PearPkgMappingElement();
- $this->elements[] = $e;
- return $e;
- }
-
- }