New file |
0,0 → 1,1595 |
<?php |
// |
// +------------------------------------------------------------------------+ |
// | PEAR :: Package File Manager | |
// +------------------------------------------------------------------------+ |
// | Copyright (c) 2003-2004 Gregory Beaver | |
// | Email cellog@phpdoc.org | |
// +------------------------------------------------------------------------+ |
// | This source file is subject to version 3.00 of the PHP License, | |
// | that is available at http://www.php.net/license/3_0.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +------------------------------------------------------------------------+ |
// | Portions of this code based on phpDocumentor | |
// | Web http://www.phpdoc.org | |
// | Mirror http://phpdocu.sourceforge.net/ | |
// +------------------------------------------------------------------------+ |
// $Id: PackageFileManager.php,v 1.42 2005/04/06 22:21:20 cellog Exp $ |
// |
|
/** |
* @package PEAR_PackageFileManager |
*/ |
/** |
* PEAR installer |
*/ |
require_once 'PEAR/Common.php'; |
/**#@+ |
* Error Codes |
*/ |
define('PEAR_PACKAGEFILEMANAGER_NOSTATE', 1); |
define('PEAR_PACKAGEFILEMANAGER_NOVERSION', 2); |
define('PEAR_PACKAGEFILEMANAGER_NOPKGDIR', 3); |
define('PEAR_PACKAGEFILEMANAGER_NOBASEDIR', 4); |
define('PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND', 5); |
define('PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND_ANYWHERE', 6); |
define('PEAR_PACKAGEFILEMANAGER_CANTWRITE_PKGFILE', 7); |
define('PEAR_PACKAGEFILEMANAGER_DEST_UNWRITABLE', 8); |
define('PEAR_PACKAGEFILEMANAGER_CANTCOPY_PKGFILE', 9); |
define('PEAR_PACKAGEFILEMANAGER_CANTOPEN_TMPPKGFILE', 10); |
define('PEAR_PACKAGEFILEMANAGER_PATH_DOESNT_EXIST', 11); |
define('PEAR_PACKAGEFILEMANAGER_NOCVSENTRIES', 12); |
define('PEAR_PACKAGEFILEMANAGER_DIR_DOESNT_EXIST', 13); |
define('PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS', 14); |
define('PEAR_PACKAGEFILEMANAGER_NOPACKAGE', 15); |
define('PEAR_PACKAGEFILEMANAGER_WRONG_MROLE', 16); |
define('PEAR_PACKAGEFILEMANAGER_NOSUMMARY', 17); |
define('PEAR_PACKAGEFILEMANAGER_NODESC', 18); |
define('PEAR_PACKAGEFILEMANAGER_ADD_MAINTAINERS', 19); |
define('PEAR_PACKAGEFILEMANAGER_NO_FILES', 20); |
define('PEAR_PACKAGEFILEMANAGER_IGNORED_EVERYTHING', 21); |
define('PEAR_PACKAGEFILEMANAGER_INVALID_PACKAGE', 22); |
define('PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE', 23); |
define('PEAR_PACKAGEFILEMANAGER_INVALID_ROLE', 24); |
define('PEAR_PACKAGEFILEMANAGER_PHP_NOT_PACKAGE', 25); |
define('PEAR_PACKAGEFILEMANAGER_CVS_PACKAGED', 26); |
define('PEAR_PACKAGEFILEMANAGER_NO_PHPCOMPATINFO', 27); |
/**#@-*/ |
/** |
* Error messages |
* @global array $GLOBALS['_PEAR_PACKAGEFILEMANAGER_ERRORS'] |
*/ |
$GLOBALS['_PEAR_PACKAGEFILEMANAGER_ERRORS'] = |
array( |
'en' => |
array( |
PEAR_PACKAGEFILEMANAGER_NOSTATE => |
'Release State (option \'state\') must by specified in PEAR_PackageFileManager setOptions (alpha|beta|stable)', |
PEAR_PACKAGEFILEMANAGER_NOVERSION => |
'Release Version (option \'version\') must be specified in PEAR_PackageFileManager setOptions', |
PEAR_PACKAGEFILEMANAGER_NOPKGDIR => |
'Package source base directory (option \'packagedirectory\') must be ' . |
'specified in PEAR_PackageFileManager setOptions', |
PEAR_PACKAGEFILEMANAGER_NOBASEDIR => |
'Package install base directory (option \'baseinstalldir\') must be ' . |
'specified in PEAR_PackageFileManager setOptions', |
PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND => |
'Base class "%s" can\'t be located', |
PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND_ANYWHERE => |
'Base class "%s" can\'t be located in default or user-specified directories', |
PEAR_PACKAGEFILEMANAGER_CANTWRITE_PKGFILE => |
'Failed to write package.xml file to destination directory', |
PEAR_PACKAGEFILEMANAGER_DEST_UNWRITABLE => |
'Destination directory "%s" is unwritable', |
PEAR_PACKAGEFILEMANAGER_CANTCOPY_PKGFILE => |
'Failed to copy package.xml.tmp file to package.xml', |
PEAR_PACKAGEFILEMANAGER_CANTOPEN_TMPPKGFILE => |
'Failed to open temporary file "%s" for writing', |
PEAR_PACKAGEFILEMANAGER_PATH_DOESNT_EXIST => |
'package.xml file path "%s" doesn\'t exist or isn\'t a directory', |
PEAR_PACKAGEFILEMANAGER_NOCVSENTRIES => |
'Directory "%s" is not a CVS directory (it must have the CVS/Entries file)', |
PEAR_PACKAGEFILEMANAGER_DIR_DOESNT_EXIST => |
'Package source base directory "%s" doesn\'t exist or isn\'t a directory', |
PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS => |
'Run $managerclass->setOptions() before any other methods', |
PEAR_PACKAGEFILEMANAGER_NOPACKAGE => |
'Package Name (option \'package\') must by specified in PEAR_PackageFileManager '. |
'setOptions to create a new package.xml', |
PEAR_PACKAGEFILEMANAGER_NOSUMMARY => |
'Package Summary (option \'summary\') must by specified in PEAR_PackageFileManager' . |
' setOptions to create a new package.xml', |
PEAR_PACKAGEFILEMANAGER_NODESC => |
'Detailed Package Description (option \'description\') must be' . |
' specified in PEAR_PackageFileManager setOptions to create a new package.xml', |
PEAR_PACKAGEFILEMANAGER_WRONG_MROLE => |
'Maintainer role must be one of "%s", was "%s"', |
PEAR_PACKAGEFILEMANAGER_ADD_MAINTAINERS => |
'Add maintainers to a package before generating the package.xml', |
PEAR_PACKAGEFILEMANAGER_NO_FILES => |
'No files found, check the path "%s"', |
PEAR_PACKAGEFILEMANAGER_IGNORED_EVERYTHING => |
'No files left, check the path "%s" and ignore option "%s"', |
PEAR_PACKAGEFILEMANAGER_INVALID_PACKAGE => |
'Package validation failed:%s%s', |
PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE => |
'Replacement Type must be one of "%s", was passed "%s"', |
PEAR_PACKAGEFILEMANAGER_INVALID_ROLE => |
'Invalid file role passed to addRole, must be one of "%s", was passed "%s"', |
PEAR_PACKAGEFILEMANAGER_PHP_NOT_PACKAGE => |
'addDependency had PHP as a package, use type="php"', |
PEAR_PACKAGEFILEMANAGER_CVS_PACKAGED => |
'path "%path%" contains CVS directory', |
PEAR_PACKAGEFILEMANAGER_NO_PHPCOMPATINFO => |
'PHP_Compat is not installed, cannot detect dependencies', |
), |
// other language translations go here |
); |
/** |
* PEAR :: PackageFileManager updates the <filelist></filelist> section |
* of a PEAR package.xml file to reflect the current files in |
* preparation for a release. |
* |
* The PEAR_PackageFileManager class uses a plugin system to generate the |
* list of files in a package. This allows both standard recursive |
* directory parsing (plugin type file) and more intelligent options |
* such as the CVS browser {@link PEAR_PackageFileManager_Cvs}, which |
* grabs all files in a local CVS checkout to create the list, ignoring |
* any other local files. |
* |
* Other options include specifying roles for file extensions (all .php |
* files are role="php", for example), roles for directories (all directories |
* named "tests" are given role="tests" by default), and exceptions. |
* Exceptions are specific pathnames with * and ? wildcards that match |
* a default role, but should have another. For example, perhaps |
* a debug.tpl template would normally be data, but should be included |
* in the docs role. Along these lines, to exclude files entirely, |
* use the ignore option. |
* |
* Required options for a release include version, baseinstalldir, state, |
* and packagedirectory (the full path to the local location of the |
* package to create a package.xml file for) |
* |
* Example usage: |
* <code> |
* <?php |
* require_once('PEAR/PackageFileManager.php'); |
* $packagexml = new PEAR_PackageFileManager; |
* $e = $packagexml->setOptions( |
* array('baseinstalldir' => 'PhpDocumentor', |
* 'version' => '1.2.1', |
* 'packagedirectory' => 'C:/Web Pages/chiara/phpdoc2/', |
* 'state' => 'stable', |
* 'filelistgenerator' => 'cvs', // generate from cvs, use file for directory |
* 'notes' => 'We\'ve implemented many new and exciting features', |
* 'ignore' => array('TODO', 'tests/'), // ignore TODO, all files in tests/ |
* 'installexceptions' => array('phpdoc' => '/*'), // baseinstalldir ="/" for phpdoc |
* 'dir_roles' => array('tutorials' => 'doc'), |
* 'exceptions' => array('README' => 'doc', // README would be data, now is doc |
* 'PHPLICENSE.txt' => 'doc'))); // same for the license |
* if (PEAR::isError($e)) { |
* echo $e->getMessage(); |
* die(); |
* } |
* $e = $test->addPlatformException('pear-phpdoc.bat', 'windows'); |
* if (PEAR::isError($e)) { |
* echo $e->getMessage(); |
* exit; |
* } |
* $packagexml->addRole('pkg', 'doc'); // add a new role mapping |
* if (PEAR::isError($e)) { |
* echo $e->getMessage(); |
* exit; |
* } |
* // replace @PHP-BIN@ in this file with the path to php executable! pretty neat |
* $e = $test->addReplacement('pear-phpdoc', 'pear-config', '@PHP-BIN@', 'php_bin'); |
* if (PEAR::isError($e)) { |
* echo $e->getMessage(); |
* exit; |
* } |
* $e = $test->addReplacement('pear-phpdoc.bat', 'pear-config', '@PHP-BIN@', 'php_bin'); |
* if (PEAR::isError($e)) { |
* echo $e->getMessage(); |
* exit; |
* } |
* // note use of {@link debugPackageFile()} - this is VERY important |
* if (isset($_GET['make']) || (isset($_SERVER['argv'][2]) && |
* $_SERVER['argv'][2] == 'make')) { |
* $e = $packagexml->writePackageFile(); |
* } else { |
* $e = $packagexml->debugPackageFile(); |
* } |
* if (PEAR::isError($e)) { |
* echo $e->getMessage(); |
* die(); |
* } |
* ?> |
* </code> |
* |
* In addition, a package.xml file can now be generated from |
* scratch, with the usage of new options package, summary, description, and |
* the use of the {@link addMaintainer()} method |
* @package PEAR_PackageFileManager |
*/ |
class PEAR_PackageFileManager |
{ |
/** |
* Format: array(array(regexp-ready string to search for whole path, |
* regexp-ready string to search for basename of ignore strings),...) |
* @var false|array |
* @access private |
*/ |
var $_ignore = false; |
|
/** |
* Contents of the package.xml file |
* @var string |
* @access private |
*/ |
var $_packageXml = false; |
|
/** |
* Contents of the original package.xml file, if any |
* @var string |
* @access private |
*/ |
var $_oldPackageXml = false; |
|
/** |
* @access private |
* @var PEAR_Common |
*/ |
var $_pear; |
|
/** |
* @access private |
* @var array |
*/ |
var $_warningStack = array(); |
|
/** |
* flag used to determine whether to use PHP_CompatInfo to detect deps |
* @var boolean |
* @access private |
*/ |
var $_detectDependencies = false; |
|
/** |
* @access private |
* @var string |
*/ |
var $_options = array( |
'packagefile' => 'package.xml', |
'doctype' => 'http://pear.php.net/dtd/package-1.0', |
'filelistgenerator' => 'file', |
'license' => 'PHP License', |
'changelogoldtonew' => true, |
'roles' => |
array( |
'php' => 'php', |
'html' => 'doc', |
'*' => 'data', |
), |
'dir_roles' => |
array( |
'docs' => 'doc', |
'examples' => 'doc', |
'tests' => 'test', |
), |
'exceptions' => array(), |
'installexceptions' => array(), |
'installas' => array(), |
'platformexceptions' => array(), |
'scriptphaseexceptions' => array(), |
'ignore' => array(), |
'include' => false, |
'deps' => false, |
'maintainers' => false, |
'notes' => '', |
'changelognotes' => false, |
'outputdirectory' => false, |
'pathtopackagefile' => false, |
'lang' => 'en', |
'configure_options' => array(), |
'replacements' => array(), |
'pearcommonclass' => false, |
'simpleoutput' => false, |
'addhiddenfiles' => false, |
'cleardependencies' => false, |
); |
|
/** |
* Does nothing, use setOptions |
* |
* The constructor is not used in order to be able to |
* return a PEAR_Error from setOptions |
* @see setOptions() |
*/ |
function PEAR_PackageFileManager() |
{ |
} |
|
/** |
* Set package.xml generation options |
* |
* The options array is indexed as follows: |
* <code> |
* $options = array('option_name' => <optionvalue>); |
* </code> |
* |
* The documentation below simplifies this description through |
* the use of option_name without quotes |
* |
* Configuration options: |
* - lang: lang controls the language in which error messages are |
* displayed. There are currently only English error messages, |
* but any contributed will be added over time.<br> |
* Possible values: en (default) |
* - packagefile: the name of the packagefile, defaults to package.xml |
* - pathtopackagefile: the path to an existing package file to read in, |
* if different from the packagedirectory |
* - packagedirectory: the path to the base directory of the package. For |
* package PEAR_PackageFileManager, this path is |
* /path/to/pearcvs/pear/PEAR_PackageFileManager where |
* /path/to/pearcvs is a local path on your hard drive |
* - outputdirectory: the path in which to place the generated package.xml |
* by default, this is ignored, and the package.xml is |
* created in the packagedirectory |
* - filelistgenerator: the <filelist> section plugin which will be used. |
* In this release, there are two generator plugins, |
* file and cvs. For details, see the docs for these |
* plugins |
* - usergeneratordir: For advanced users. If you write your own filelist |
* generator plugin, use this option to tell |
* PEAR_PackageFileManager where to find the file that |
* contains it. If the plugin is named foo, the class |
* must be named PEAR_PackageFileManager_Foo |
* no matter where it is located. By default, the Foo |
* plugin is located in PEAR/PackageFileManager/Foo.php. |
* If you pass /path/to/foo in this option, setOptions |
* will look for PEAR_PackageFileManager_Foo in |
* /path/to/foo/Foo.php |
* - doctype: Specifies the DTD of the package.xml file. Default is |
* http://pear.php.net/dtd/package-1.0 |
* - pearcommonclass: Specifies the name of the class to instantiate, default |
* is PEAR_Common, but users can override this with a custom |
* class that implements PEAR_Common's method interface |
* - changelogoldtonew: True if the ChangeLog should list from oldest entry to |
* newest. Set to false if you would like new entries first |
* - simpleoutput: True if the package.xml should not contain md5sum or <provides /> |
* for readability |
* - addhiddenfiles: True if you wish to add hidden files/directories that begin with . |
* like .bashrc. This is only used by the File generator. The CVS |
* generator will use all files in CVS regardless of format |
* |
* package.xml simple options: |
* - baseinstalldir: The base directory to install this package in. For |
* package PEAR_PackageFileManager, this is "PEAR", for |
* package PEAR, this is "/" |
* - license: The license this release is released under. Default is |
* PHP License if left unspecified |
* - notes: Release notes, any text describing what makes this release unique |
* - changelognotes: notes for the changelog, this should be more detailed than |
* the release notes. By default, PEAR_PackageFileManager uses |
* the notes option for the changelog as well |
* - version: The version number for this release. Remember the convention for |
* numbering: initial alpha is between 0 and 1, add b<beta number> for |
* beta as in 1.0b1, the integer portion of the version should specify |
* backwards compatibility, as in 1.1 is backwards compatible with 1.0, |
* but 2.0 is not backwards compatible with 1.10. Also note that 1.10 |
* is a greater release version than 1.1 (think of it as "one point ten" |
* and "one point one"). Bugfix releases should be a third decimal as in |
* 1.0.1, 1.0.2 |
* - package: [optional] Package name. Use this to create a new package.xml, or |
* overwrite an existing one from another package used as a template |
* - summary: [optional] Summary of package purpose |
* - description: [optional] Description of package purpose. Note that the above |
* three options are not optional when creating a new package.xml |
* from scratch |
* |
* <b>WARNING</b>: all complex options that require a file path are case-sensitive |
* |
* package.xml complex options: |
* - cleardependencies: since version 1.3.0, this option will erase any existing |
* dependencies in the package.xml if set to true |
* - ignore: an array of filenames, directory names, or wildcard expressions specifying |
* files to exclude entirely from the package.xml. Wildcards are operating system |
* wildcards * and ?. file*foo.php will exclude filefoo.php, fileabrfoo.php and |
* filewho_is_thisfoo.php. file?foo.php will exclude fileafoo.php and will not |
* exclude fileaafoo.php. test/ will exclude all directories and subdirectories of |
* ANY directory named test encountered in directory parsing. *test* will exclude |
* all files and directories that contain test in their name |
* - include: an array of filenames, directory names, or wildcard expressions specifying |
* files to include in the listing. All other files will be ignored. |
* Wildcards are in the same format as ignore |
* - roles: this is an array mapping file extension to install role. This |
* specifies default behavior that can be overridden by the exceptions |
* option and dir_roles option. use {@link addRole()} to add a new |
* role to the pre-existing array |
* - dir_roles: this is an array mapping directory name to install role. All |
* files in a directory whose name matches the directory will be |
* given the install role specified. Single files can be excluded |
* from this using the exceptions option. The directory should be |
* a relative path from the baseinstalldir, or "/" for the baseinstalldir |
* - exceptions: specify file role for specific files. This array maps all files |
* matching the exact name of a file to a role as in "file.ext" => "role" |
* - deps: dependency array. Pass in an empty array to clear all dependencies, and use |
* {@link addDependency()} to add new ones/replace existing ones |
* - maintainers: maintainers array. Pass in an empty array to clear all maintainers, and |
* use {@link addMaintainer()} to add a new maintainer/replace existing maintainer |
* - installexceptions: array mapping of specific filenames to baseinstalldir values. Use |
* this to force the installation of a file into another directory, |
* such as forcing a script to be in the root scripts directory so that |
* it will be in the path. The filename must be a relative path to the |
* packagedirectory |
* - platformexceptions: array mapping of specific filenames to the platform they should be |
* installed on. Use this to specify unix-only files or windows-only |
* files. The format of the platform string must be |
* OS-version-cpu-extra if any more specific information is needed, |
* and the OS must be in lower case as in "windows." The match is |
* performed using a regular expression, but uses * and ? wildcards |
* instead of .* and .?. Note that hpux/aix/irix/linux are all |
* exclusive. To select non-windows, use (*ix|*ux) |
* - scriptphaseexceptions: array mapping of scripts to their install phase. This can be |
* one of: pre-install, post-install, pre-uninstall, post-uninstall, |
* pre-build, post-build, pre-setup, or post-setup |
* - installas: array mapping of specific filenames to the filename they should be installed as. |
* Use this to specify new filenames for files that should be installed. This will |
* often be used in conjunction with platformexceptions if there are two files for |
* different OSes that must have the same name when installed. |
* - replacements: array mapping of specific filenames to complex text search-and-replace that |
* should be performed upon install. The format is: |
* <pre> |
* filename => array('type' => php-const|pear-config|package-info |
* 'from' => text in file |
* 'to' => name of variable) |
* </pre> |
* if type is php-const, then 'to' must be the name of a PHP Constant. |
* If type is pear-config, then 'to' must be the name of a PEAR config |
* variable accessible through a PEAR_Config class->get() method. If |
* type is package-info, then 'to' must be the name of a section from |
* the package.xml file used to install this file. |
* - globalreplacements: a list of replacements that should be performed on every single file. |
* The format is the same as replacements (since 1.4.0) |
* - configure_options: array specifies build options for PECL packages (you should probably |
* use PECL_Gen instead, but it's here for completeness) |
* @see PEAR_PackageFileManager_File |
* @see PEAR_PackageFileManager_CVS |
* @return void|PEAR_Error |
* @throws PEAR_PACKAGEFILEMANAGER_NOSTATE |
* @throws PEAR_PACKAGEFILEMANAGER_NOVERSION |
* @throws PEAR_PACKAGEFILEMANAGER_NOPKGDIR |
* @throws PEAR_PACKAGEFILEMANAGER_NOBASEDIR |
* @throws PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND_ANYWHERE |
* @throws PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND |
* @param array |
*/ |
function setOptions($options = array(), $internal = false) |
{ |
if (!$internal) { |
if (!isset($options['state'])) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOSTATE); |
} |
if (!isset($options['version'])) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOVERSION); |
} |
} |
if (!isset($options['packagedirectory']) && !$internal) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOPKGDIR); |
} elseif (isset($options['packagedirectory'])) { |
$options['packagedirectory'] = str_replace(DIRECTORY_SEPARATOR, |
'/', |
realpath($options['packagedirectory'])); |
if ($options['packagedirectory']{strlen($options['packagedirectory']) - 1} != '/') { |
$options['packagedirectory'] .= '/'; |
} |
} |
if (isset($options['pathtopackagefile'])) { |
$options['pathtopackagefile'] = str_replace(DIRECTORY_SEPARATOR, |
'/', |
realpath($options['pathtopackagefile'])); |
if ($options['pathtopackagefile']{strlen($options['pathtopackagefile']) - 1} != '/') { |
$options['pathtopackagefile'] .= '/'; |
} |
} |
if (!isset($options['baseinstalldir']) && !$internal) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOBASEDIR); |
} |
$this->_options = array_merge($this->_options, $options); |
|
if (!class_exists($this->_options['pearcommonclass'])) { |
if ($this->_options['simpleoutput']) { |
if ($this->isIncludeable('PEAR/PackageFile/Generator/v1.php')) { |
include_once 'PEAR/PackageFileManager/SimpleGenerator.php'; |
$this->_options['pearcommonclass'] = 'PEAR_PackageFileManager_SimpleGenerator'; |
} else { |
include_once 'PEAR/PackageFileManager/XMLOutput.php'; |
$this->_options['pearcommonclass'] = 'PEAR_PackageFileManager_XMLOutput'; |
} |
} else { |
$this->_options['pearcommonclass'] = 'PEAR_Common'; |
} |
} |
$path = ($this->_options['pathtopackagefile'] ? |
$this->_options['pathtopackagefile'] : $this->_options['packagedirectory']); |
$this->_options['filelistgenerator'] = |
ucfirst(strtolower($this->_options['filelistgenerator'])); |
if (!$internal) { |
if (PEAR::isError($res = |
$this->_getExistingPackageXML($path, $this->_options['packagefile']))) { |
return $res; |
} |
} |
if (!class_exists('PEAR_PackageFileManager_' . $this->_options['filelistgenerator'])) { |
// attempt to load the interface from the standard PEAR location |
if ($this->isIncludeable('PEAR/PackageFileManager/' . |
$this->_options['filelistgenerator'] . '.php')) { |
include_once('PEAR/PackageFileManager/' . |
$this->_options['filelistgenerator'] . '.php'); |
} elseif (isset($this->_options['usergeneratordir'])) { |
// attempt to load from a user-specified directory |
if (is_dir(realpath($this->_options['usergeneratordir']))) { |
$this->_options['usergeneratordir'] = |
str_replace(DIRECTORY_SEPARATOR, |
'/', |
realpath($this->_options['usergeneratordir'])); |
if ($this->_options['usergeneratordir']{strlen($this->_options['usergeneratordir']) |
- 1} != '/') { |
$this->_options['usergeneratordir'] .= '/'; |
} |
} else { |
$this->_options['usergeneratordir'] = '////'; |
} |
if (file_exists($this->_options['usergeneratordir'] . |
$this->_options['filelistgenerator'] . '.php') && |
is_readable($this->_options['usergeneratordir'] . |
$this->_options['filelistgenerator'] . '.php')) { |
include_once($this->_options['usergeneratordir'] . |
$this->_options['filelistgenerator'] . '.php'); |
} |
if (!class_exists('PEAR_PackageFileManager_' . $this->_options['filelistgenerator'])) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND_ANYWHERE, |
'PEAR_PackageFileManager_' . $this->_options['filelistgenerator']); |
} |
} else { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND, |
'PEAR_PackageFileManager_' . $this->_options['filelistgenerator']); |
} |
} |
} |
|
/** |
* Import options from an existing package.xml |
* |
* @return true|PEAR_Error |
*/ |
function importOptions($packagefile, $options = array()) |
{ |
$options['cleardependencies'] = $options['deps'] = $options['maintainers'] = false; |
$this->setOptions($options, true); |
if (PEAR::isError($res = $this->_getExistingPackageXML(dirname($packagefile) . |
DIRECTORY_SEPARATOR, basename($packagefile)))) { |
return $res; |
} |
$this->_options['package'] = $this->_oldPackageXml['package']; |
$this->_options['summary'] = $this->_oldPackageXml['summary']; |
$this->_options['description'] = $this->_oldPackageXml['description']; |
$this->_options['date'] = $this->_oldPackageXml['release_date']; |
$this->_options['version'] = $this->_oldPackageXml['version']; |
$this->_options['license'] = $this->_oldPackageXml['release_license']; |
$this->_options['state'] = $this->_oldPackageXml['release_state']; |
$this->_options['notes'] = $this->_oldPackageXml['release_notes']; |
if (isset($this->_oldPackagexml['release_deps'])) { |
$this->_options['deps'] = $this->_oldPackageXml['release_deps']; |
} |
$this->_options['maintainers'] = $this->_oldPackageXml['maintainers']; |
return true; |
} |
|
/** |
* Get the existing options |
* @return array |
*/ |
function getOptions() |
{ |
return $this->_options; |
} |
|
/** |
* Add an extension/role mapping to the role mapping option |
* |
* Roles influence both where a file is installed and how it is installed. |
* Files with role="data" are in a completely different directory hierarchy |
* from the program files of role="php" |
* |
* In PEAR 1.3b2, these roles are |
* - php (most common) |
* - data |
* - doc |
* - test |
* - script (gives the file an executable attribute) |
* - src |
* @param string file extension |
* @param string role |
* @throws PEAR_PACKAGEFILEMANAGER_INVALID_ROLE |
*/ |
function addRole($extension, $role) |
{ |
$roles = call_user_func(array($this->_options['pearcommonclass'], 'getfileroles')); |
if (!in_array($role, $roles)) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_INVALID_ROLE, implode($roles, ', '), $role); |
} |
$this->_options['roles'][$extension] = $role; |
} |
|
/** |
* Add an install-time platform conditional install for a file |
* |
* The format of the platform string must be |
* OS-version-cpu-extra if any more specific information is needed, |
* and the OS must be in lower case as in "windows." The match is |
* performed using a regular expression, but uses * and ? wildcards |
* instead of .* and .?. Note that hpux/aix/irix/linux are all |
* exclusive. To select non-windows, use (*ix|*ux) |
* |
* This information is based on eyeing the source for OS/Guess.php, so |
* if you are unsure of what to do, read that file. |
* @param string relative path of file (relative to packagedirectory option) |
* @param string platform descriptor string |
*/ |
function addPlatformException($path, $platform) |
{ |
if (!isset($this->_options['platformexceptions'])) { |
$this->_options['platformexceptions'] = array(); |
} |
$this->_options['platformexceptions'][$path] = $platform; |
} |
|
/** |
* Add a replacement option for all files |
* |
* This sets an install-time complex search-and-replace function |
* allowing the setting of platform-specific variables in all |
* installed files. |
* |
* if $type is php-const, then $to must be the name of a PHP Constant. |
* If $type is pear-config, then $to must be the name of a PEAR config |
* variable accessible through a {@link PEAR_Config::get()} method. If |
* type is package-info, then $to must be the name of a section from |
* the package.xml file used to install this file. |
* @param string relative path of file (relative to packagedirectory option) |
* @param string variable type, either php-const, pear-config or package-info |
* @param string text to replace in the source file |
* @param string variable name to use for replacement |
* @throws PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE |
*/ |
function addGlobalReplacement($type, $from, $to) |
{ |
if (!isset($this->_options['globalreplacements'])) { |
$this->_options['globalreplacements'] = array(); |
} |
$types = call_user_func(array($this->_options['pearcommonclass'], 'getreplacementtypes')); |
if (!in_array($type, $types)) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE, |
implode($types, ', '), $type); |
} |
$this->_options['globalreplacements'][] = |
array('type' => $type, 'from' => $from, 'to' => $to); |
} |
|
/** |
* Add a replacement option for a file |
* |
* This sets an install-time complex search-and-replace function |
* allowing the setting of platform-specific variables in an |
* installed file. |
* |
* if $type is php-const, then $to must be the name of a PHP Constant. |
* If $type is pear-config, then $to must be the name of a PEAR config |
* variable accessible through a {@link PEAR_Config::get()} method. If |
* type is package-info, then $to must be the name of a section from |
* the package.xml file used to install this file. |
* @param string relative path of file (relative to packagedirectory option) |
* @param string variable type, either php-const, pear-config or package-info |
* @param string text to replace in the source file |
* @param string variable name to use for replacement |
* @throws PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE |
*/ |
function addReplacement($path, $type, $from, $to) |
{ |
if (!isset($this->_options['replacements'])) { |
$this->_options['replacements'] = array(); |
} |
$types = call_user_func(array($this->_options['pearcommonclass'], 'getreplacementtypes')); |
if (!in_array($type, $types)) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE, |
implode($types, ', '), $type); |
} |
$this->_options['replacements'][$path][] = array('type' => $type, 'from' => $from, 'to' => $to); |
} |
|
/** |
* Add a maintainer to the list of maintainers. |
* |
* Every maintainer must have a valid account at pear.php.net. The |
* first parameter is the account name (for instance, cellog is the |
* handle for Greg Beaver at pear.php.net). Every maintainer has |
* one of four possible roles: |
* - lead: the primary maintainer |
* - developer: an important developer on the project |
* - contributor: self-explanatory |
* - helper: ditto |
* |
* Finally, specify the name and email of the maintainer |
* @param string username on pear.php.net of maintainer |
* @param lead|developer|contributor|helper role of maintainer |
* @param string full name of maintainer |
* @param string email address of maintainer |
*/ |
function addMaintainer($handle, $role, $name, $email) |
{ |
if (!$this->_packageXml) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS); |
} |
if (!in_array($role, $GLOBALS['_PEAR_Common_maintainer_roles'])) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_WRONG_MROLE, |
implode(', ', call_user_func(array($this->_options['pearcommonclass'], |
'getUserRoles'))), |
$role); |
} |
if (!isset($this->_packageXml['maintainers'])) { |
$this->_packageXml['maintainers'] = array(); |
} |
$found = false; |
foreach($this->_packageXml['maintainers'] as $index => $maintainer) { |
if ($maintainer['handle'] == $handle) { |
$found = $index; |
break; |
} |
} |
$maintainer = |
array('handle' => $handle, 'role' => $role, 'name' => $name, 'email' => $email); |
if ($found !== false) { |
$this->_packageXml['maintainers'][$found] = $maintainer; |
} else { |
$this->_packageXml['maintainers'][] = $maintainer; |
} |
} |
|
/** |
* Add an install-time configuration option for building of source |
* |
* This option is only useful to PECL projects that are built upon |
* installation |
* @param string name of the option |
* @param string prompt to display to the user |
* @param string default value |
* @throws PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS |
* @return void|PEAR_Error |
*/ |
function addConfigureOption($name, $prompt, $default = null) |
{ |
if (!$this->_packageXml) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS); |
} |
if (!isset($this->_packageXml['configure_options'])) { |
$this->_packageXml['configure_options'] = array(); |
} |
$found = false; |
foreach($this->_packageXml['configure_options'] as $index => $option) { |
if ($option['name'] == $name) { |
$found = $index; |
break; |
} |
} |
$option = array('name' => $name, 'prompt' => $prompt); |
if (isset($default)) { |
$option['default'] = $default; |
} |
if ($found !== false) { |
$this->_packageXml['configure_options'][$found] = $option; |
} else { |
$this->_packageXml['configure_options'][] = $option; |
} |
} |
|
/** |
* @return void|PEAR_Error |
* @throws PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS |
*/ |
function detectDependencies() |
{ |
if (!$this->_packageXml) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS); |
} |
if (!$this->isIncludeable('PHP/CompatInfo.php')) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_PHP_COMPAT_NOT_INSTALLED); |
} else { |
if (include_once('PHP/CompatInfo.php')) { |
$this->_detectDependencies = true; |
} else { |
$this->raiseError(PEAR_PACKAGEFILEMANAGER_NO_PHPCOMPATINFO); |
} |
} |
} |
|
function isIncludeable($file) |
{ |
if (!defined('PATH_SEPARATOR')) { |
define('PATH_SEPARATOR', strtolower(substr(PHP_OS, 0, 3)) == 'win' ? ';' : ':'); |
} |
foreach (explode(PATH_SEPARATOR, ini_get('include_path')) as $path) { |
if (file_exists($path . DIRECTORY_SEPARATOR . $file) && |
is_readable($path . DIRECTORY_SEPARATOR . $file)) { |
return true; |
} |
} |
return false; |
} |
|
/** |
* Add a dependency on another package, or an extension/php |
* |
* This will overwrite an existing dependency if it is found. In |
* other words, if a dependency on PHP 4.1.0 exists, and |
* addDependency('php', '4.3.0', 'ge', 'php') is called, the existing |
* dependency on PHP 4.1.0 will be overwritten with the new one on PHP 4.3.0 |
* @param string Dependency element name |
* @param string Dependency version |
* @param string A specific operator for the version, this can be one of: |
* 'has', 'not', 'lt', 'le', 'eq', 'ne', 'ge', or 'gt' |
* @param string Dependency type. This can be one of: |
* 'pkg', 'ext', 'php', 'prog', 'os', 'sapi', or 'zend' |
* @param boolean true if dependency is optional |
* @throws PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS |
* @throws PEAR_PACKAGEFILEMANAGER_PHP_NOT_PACKAGE |
* @return void|PEAR_Error |
*/ |
function addDependency($name, $version = false, $operator = 'ge', $type = 'pkg', $optional = false) |
{ |
if (!$this->_packageXml) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS); |
} |
if ((strtolower($name) == 'php') && (strtolower($type) == 'pkg')) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_PHP_NOT_PACKAGE); |
} |
if (!isset($this->_packageXml['release_deps']) || !is_array($this->_packageXml['release_deps'])) { |
$this->_packageXml['release_deps'] = array(); |
} |
$found = false; |
foreach($this->_packageXml['release_deps'] as $index => $dep) { |
if ($type == 'php') { |
if ($dep['type'] == 'php') { |
$found = $index; |
break; |
} |
} else { |
if (isset($dep['name']) && $dep['name'] == $name && $dep['type'] == $type) { |
$found = $index; |
break; |
} |
} |
} |
$dep = |
array( |
'name' => $name, |
'type' => $type); |
if ($type == 'php') { |
unset($dep['name']); |
} |
if ($operator) { |
$dep['rel'] = $operator; |
if ($dep['rel'] != 'has' && $version) { |
$dep['version'] = $version; |
} |
} |
|
if ($optional) { |
$dep['optional'] = 'yes'; |
} else { |
$dep['optional'] = 'no'; |
} |
|
if ($found !== false) { |
$this->_packageXml['release_deps'][$found] = $dep; // overwrite existing dependency |
} else { |
$this->_packageXml['release_deps'][] = $dep; // add new dependency |
} |
} |
|
/** |
* Writes the package.xml file out with the newly created <release></release> tag |
* |
* ALWAYS use {@link debugPackageFile} to verify that output is correct before |
* overwriting your package.xml |
* @param boolean null if no debugging, true if web interface, false if command-line |
* @throws PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS |
* @throws PEAR_PACKAGEFILEMANAGER_ADD_MAINTAINERS |
* @throws PEAR_PACKAGEFILEMANAGER_CANTWRITE_PKGFILE |
* @throws PEAR_PACKAGEFILEMANAGER_CANTCOPY_PKGFILE |
* @throws PEAR_PACKAGEFILEMANAGER_CANTOPEN_TMPPKGFILE |
* @throws PEAR_PACKAGEFILEMANAGER_DEST_UNWRITABLE |
* @return void|PEAR_Error |
*/ |
function writePackageFile($debuginterface = null) |
{ |
if (!$this->_packageXml) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS); |
} |
if (!isset($this->_packageXml['maintainers']) || empty($this->_packageXml['maintainers'])) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_ADD_MAINTAINERS); |
} |
extract($this->_options); |
$date = date('Y-m-d'); |
if (isset($package)) { |
$this->_packageXml['package'] = $package; |
} |
if (isset($summary)) { |
$this->_packageXml['summary'] = $summary; |
} |
if (isset($description)) { |
$this->_packageXml['description'] = $description; |
} |
$this->_packageXml['release_date'] = $date; |
$this->_packageXml['version'] = $version; |
$this->_packageXml['release_license'] = $license; |
$this->_packageXml['release_state'] = $state; |
$this->_packageXml['release_notes'] = $notes; |
$PEAR_Common = $this->_options['pearcommonclass']; |
$this->_pear = new $PEAR_Common; |
if (method_exists($this->_pear, 'setPackageFileManager')) { |
$this->_pear->setPackageFileManager($this); |
} |
$this->_packageXml['filelist'] = $this->_getFileList(); |
$warnings = $this->getWarnings(); |
if (count($warnings)) { |
$nl = (isset($debuginterface) && $debuginterface ? '<br />' : "\n"); |
foreach($warnings as $errmsg) { |
echo 'WARNING: ' . $errmsg['message'] . $nl; |
} |
} |
if (PEAR::isError($this->_packageXml['filelist'])) { |
return $this->_packageXml['filelist']; |
} |
if (isset($this->_pear->pkginfo['provides'])) { |
$this->_packageXml['provides'] = $this->_pear->pkginfo['provides']; |
} |
if ($this->_options['simpleoutput']) { |
unset($this->_packageXml['provides']); |
} |
$this->_packageXml['release_deps'] = $this->_getDependencies(); |
$this->_updateChangeLog(); |
|
$common = &$this->_pear; |
$warnings = $errors = array(); |
if (method_exists($common, 'setPackageFileManagerOptions')) { |
$common->setPackageFileManagerOptions($this->_options); |
} |
$packagexml = $common->xmlFromInfo($this->_packageXml); |
$common->validatePackageInfo($packagexml, $warnings, $errors, |
$this->_options['packagedirectory']); |
if (count($errors)) { |
$ret = ''; |
$nl = (isset($debuginterface) && $debuginterface ? '<br />' : "\n"); |
foreach($errors as $errmsg) { |
$ret .= $errmsg . $nl; |
} |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_INVALID_PACKAGE, $nl, $ret); |
} |
if (count($warnings)) { |
$nl = (isset($debuginterface) && $debuginterface ? '<br />' : "\n"); |
foreach($warnings as $errmsg) { |
echo $errmsg . $nl; |
} |
} |
if (!strpos($packagexml, '<!DOCTYPE')) { |
// hack to fix pear |
$packagexml = str_replace('<package version="1.0">', |
'<!DOCTYPE package SYSTEM "' . $this->_options['doctype'] . |
"\">\n<package version=\"1.0\">", |
$packagexml); |
} |
if (isset($debuginterface)) { |
if ($debuginterface) { |
echo '<pre>' . htmlentities($packagexml) . '</pre>'; |
} else { |
echo $packagexml; |
} |
return true; |
} |
$outputdir = ($this->_options['outputdirectory'] ? |
$this->_options['outputdirectory'] : $this->_options['packagedirectory']); |
if ((file_exists($outputdir . $this->_options['packagefile']) && |
is_writable($outputdir . $this->_options['packagefile'])) |
|| |
@touch($outputdir . $this->_options['packagefile'])) { |
if ($fp = @fopen($outputdir . $this->_options['packagefile'] . '.tmp', "w")) { |
$written = @fwrite($fp, $packagexml); |
@fclose($fp); |
if ($written === false) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_CANTWRITE_PKGFILE); |
} |
if (!@copy($outputdir . $this->_options['packagefile'] . '.tmp', |
$outputdir . $this->_options['packagefile'])) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_CANTCOPY_PKGFILE); |
} else { |
@unlink($outputdir . $this->_options['packagefile'] . '.tmp'); |
return true; |
} |
} else { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_CANTOPEN_TMPPKGFILE, |
$outputdir . $this->_options['packagefile'] . '.tmp'); |
} |
} else { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_DEST_UNWRITABLE, $outputdir); |
} |
} |
|
/** |
* ALWAYS use this to test output before overwriting your package.xml!! |
* |
* This method instructs writePackageFile() to simply print the package.xml |
* to output, either command-line or web-friendly (this is automatic |
* based on the value of php_sapi_name()) |
* @uses writePackageFile() calls with the debug parameter set based on |
* whether it is called from the command-line or web interface |
*/ |
function debugPackageFile() |
{ |
$webinterface = php_sapi_name() != 'cli'; |
return $this->writePackageFile($webinterface); |
} |
|
/** |
* Store a warning on the warning stack |
*/ |
function pushWarning($code, $info) |
{ |
$this->_warningStack[] = array('code' => $code, |
'message' => $this->_getMessage($code, $info)); |
} |
|
/** |
* Retrieve the list of warnings |
* @return array |
*/ |
function getWarnings() |
{ |
$a = $this->_warningStack; |
$this->_warningStack = array(); |
return $a; |
} |
|
/** |
* Retrieve an error message from a code |
* @access private |
* @return string Error message |
*/ |
function _getMessage($code, $info) |
{ |
$msg = $GLOBALS['_PEAR_PACKAGEFILEMANAGER_ERRORS'][$this->_options['lang']][$code]; |
foreach ($info as $name => $value) { |
$msg = str_replace('%' . $name . '%', $value, $msg); |
} |
return $msg; |
} |
|
/** |
* Utility function to shorten error generation code |
* |
* {@source} |
* @return PEAR_Error |
* @static |
*/ |
function raiseError($code, $i1 = '', $i2 = '') |
{ |
return PEAR::raiseError('PEAR_PackageFileManager Error: ' . |
sprintf($GLOBALS['_PEAR_PACKAGEFILEMANAGER_ERRORS'][$this->_options['lang']][$code], |
$i1, $i2), $code); |
} |
|
/** |
* Uses {@link PEAR_Common::analyzeSourceCode()} and {@link PEAR_Common::buildProvidesArray()} |
* to create the <provides></provides> section of the package.xml |
* @param PEAR_Common |
* @param string path to source file |
* @access private |
*/ |
function _addProvides(&$pear, $file) |
{ |
if (!($a = $pear->analyzeSourceCode($file))) { |
return; |
} else { |
$pear->buildProvidesArray($a); |
} |
} |
|
/** |
* @uses getDirTag() generate the xml from the array |
* @return string |
* @access private |
*/ |
function _getFileList() |
{ |
$generatorclass = 'PEAR_PackageFileManager_' . $this->_options['filelistgenerator']; |
$generator = new $generatorclass($this, $this->_options); |
if ($this->_options['simpleoutput'] && is_a($this->_pear, 'PEAR_Common')) { |
return $this->_getSimpleDirTag($this->_struc = $generator->getFileList()); |
} |
return $this->_getDirTag($this->_struc = $generator->getFileList()); |
} |
|
/** |
* Recursively generate the <filelist> section's <dir> and <file> tags, but with |
* simple human-readable output |
* @param array|PEAR_Error the sorted directory structure, or an error |
* from filelist generation |
* @param false|string whether the parent directory has a role this should |
* inherit |
* @param integer indentation level |
* @return array|PEAR_Error |
* @access private |
*/ |
function _getSimpleDirTag($struc, $role = false, $_curdir = '') |
{ |
if (PEAR::isError($struc)) { |
return $struc; |
} |
extract($this->_options); |
$ret = array(); |
foreach($struc as $dir => $files) { |
if (false && $dir === '/') { |
// global directory role? overrides all exceptions except file exceptions |
if (isset($dir_roles['/'])) { |
$role = $dir_roles['/']; |
} |
return array( |
'baseinstalldir' => $this->_options['baseinstalldir'], |
'##files' => $this->_getSimpleDirTag($struc[$dir], $role, ''), |
'name' => '/'); |
} else { |
if (!isset($files['file'])) { |
if (isset($dir_roles[$_curdir . $dir])) { |
$myrole = $dir_roles[$_curdir . $dir]; |
} else { |
$myrole = $role; |
} |
$ret[$dir] = array(); |
if ($dir == '/') { |
$ret[$dir]['baseinstalldir'] = $this->_options['baseinstalldir']; |
} |
$ret[$dir]['name'] = $dir; |
$recurdir = ($_curdir == '') ? $dir . '/' : $_curdir . $dir . '/'; |
if ($recurdir == '//') { |
$recurdir = ''; |
} |
$ret[$dir]['##files'] = $this->_getSimpleDirTag($files, $myrole, $recurdir); |
} else { |
$myrole = ''; |
if (!$role) |
{ |
$myrole = false; |
if (isset($exceptions[$files['path']])) { |
$myrole = $exceptions[$files['path']]; |
} elseif (isset($roles[$files['ext']])) { |
$myrole = $roles[$files['ext']]; |
} else { |
$myrole = $roles['*']; |
} |
} else { |
$myrole = $role; |
if (isset($exceptions[$files['path']])) { |
$myrole = $exceptions[$files['path']]; |
} |
} |
$test = explode('/', $files['path']); |
foreach ($test as $subpath) { |
if ($subpath == 'CVS') { |
$this->pushWarning(PEAR_PACKAGEFILEMANAGER_CVS_PACKAGED, |
array('path' => $files['path'])); |
} |
} |
$ret[$files['file']] = array('role' => $myrole); |
if (isset($installexceptions[$files['path']])) { |
$ret[$files['file']]['baseinstalldir'] = |
$installexceptions[$files['path']]; |
} |
if (isset($platformexceptions[$files['path']])) { |
$ret[$files['file']]['platform'] = $platformexceptions[$files['path']]; |
} |
if (isset($installas[$files['path']])) { |
$ret[$files['file']]['install-as'] = $installas[$files['path']]; |
} |
if (isset($replacements[$files['path']])) { |
$ret[$files['file']]['replacements'] = $replacements[$files['path']]; |
} |
if (isset($globalreplacements)) { |
if (!isset($ret[$files['file']]['replacements'])) { |
$ret[$files['file']]['replacements'] = array(); |
} |
$ret[$files['file']]['replacements'] = array_merge( |
$ret[$files['file']]['replacements'], $globalreplacements); |
} |
} |
} |
} |
return $ret; |
} |
|
/** |
* Recursively generate the <filelist> section's <dir> and <file> tags |
* @param array|PEAR_Error the sorted directory structure, or an error |
* from filelist generation |
* @param false|string whether the parent directory has a role this should |
* inherit |
* @param integer indentation level |
* @return array|PEAR_Error |
* @access private |
*/ |
function _getDirTag($struc, $role=false, $_curdir = '') |
{ |
if (PEAR::isError($struc)) { |
return $struc; |
} |
extract($this->_options); |
$ret = array(); |
foreach($struc as $dir => $files) { |
if ($dir === '/') { |
// global directory role? overrides all exceptions except file exceptions |
if (isset($dir_roles['/'])) { |
$role = $dir_roles['/']; |
} |
return $this->_getDirTag($struc[$dir], $role, ''); |
} else { |
if (!isset($files['file'])) { |
$myrole = ''; |
if (isset($dir_roles[$_curdir . $dir])) { |
$myrole = $dir_roles[$_curdir . $dir]; |
} elseif ($role) { |
$myrole = $role; |
} |
$ret = array_merge($ret, $this->_getDirTag($files, $myrole, $_curdir . $dir . '/')); |
} else { |
$myrole = ''; |
if (!$role) |
{ |
$myrole = false; |
if (isset($exceptions[$files['path']])) { |
$myrole = $exceptions[$files['path']]; |
} elseif (isset($roles[$files['ext']])) { |
$myrole = $roles[$files['ext']]; |
} else { |
$myrole = $roles['*']; |
} |
} else { |
$myrole = $role; |
if (isset($exceptions[$files['path']])) { |
$myrole = $exceptions[$files['path']]; |
} |
} |
if (isset($installexceptions[$files['path']])) { |
$bi = $installexceptions[$files['path']]; |
} else { |
$bi = $this->_options['baseinstalldir']; |
} |
$test = explode('/', $files['path']); |
foreach ($test as $subpath) { |
if ($subpath == 'CVS') { |
$this->pushWarning(PEAR_PACKAGEFILEMANAGER_CVS_PACKAGED, array('path' => $files['path'])); |
} |
} |
$ret[$files['path']] = |
array('role' => $myrole, |
'baseinstalldir' => $bi, |
); |
if (!isset($this->_options['simpleoutput'])) { |
$md5sum = @md5_file($this->_options['packagedirectory'] . $files['path']); |
if (!empty($md5sum)) { |
$ret[$files['path']]['md5sum'] = $md5sum; |
} |
} elseif (isset($ret[$files['path']]['md5sum'])) { |
unset($ret[$files['path']]['md5sum']); |
} |
if (isset($platformexceptions[$files['path']])) { |
$ret[$files['path']]['platform'] = $platformexceptions[$files['path']]; |
} |
if (isset($installas[$files['path']])) { |
$ret[$files['path']]['install-as'] = $installas[$files['path']]; |
} |
if (isset($replacements[$files['path']])) { |
$ret[$files['path']]['replacements'] = $replacements[$files['path']]; |
} |
if (isset($globalreplacements)) { |
if (!isset($ret[$files['path']]['replacements'])) { |
$ret[$files['path']]['replacements'] = array(); |
} |
$ret[$files['path']]['replacements'] = array_merge( |
$ret[$files['path']]['replacements'], $globalreplacements); |
} |
if ($myrole == 'php' && !$this->_options['simpleoutput']) { |
$this->_addProvides($this->_pear, $files['fullpath']); |
} |
} |
} |
} |
return $ret; |
} |
|
/** |
* @param array |
* @access private |
*/ |
function _traverseFileArray($files, &$ret) { |
foreach ($files as $file) { |
if (!isset($file['fullpath'])) { |
$this->_traverseFileArray($file, $ret); |
} else { |
$ret[] = $file['fullpath']; |
} |
} |
} |
|
/** |
* Retrieve the 'deps' option passed to the constructor |
* @access private |
* @return array |
*/ |
function _getDependencies() |
{ |
if ($this->_detectDependencies) { |
$this->_traverseFileArray($this->_struc, $ret); |
$compatinfo = new PHP_CompatInfo(); |
$info = $compatinfo->parseArray($ret); |
$ret = $this->addDependency('php',$info['version'],'ge','php',false); |
if (is_a($ret, 'PEAR_Error')) { |
return $ret; |
} |
foreach ($info['extensions'] as $ext) { |
$this->addDependency($ext, '', 'has', 'ext', false); |
} |
} |
if (isset($this->_packageXml['release_deps']) && |
is_array($this->_packageXml['release_deps'])) { |
return $this->_packageXml['release_deps']; |
} else { |
return array(); |
} |
} |
|
/** |
* Creates a changelog entry with the current release |
* notes and dates, or overwrites a previous creation |
* @access private |
*/ |
function _updateChangeLog() |
{ |
$curlog = $oldchangelog = false; |
if (!isset($this->_packageXml['changelog'])) { |
$changelog = array(); |
if (isset($this->_oldPackageXml['release_notes'])) { |
$changelog['release_notes'] = $this->_oldPackageXml['release_notes']; |
} |
if (isset($this->_oldPackageXml['version'])) { |
$changelog['version'] = $this->_oldPackageXml['version']; |
} |
if (isset($this->_oldPackageXml['release_date'])) { |
$changelog['release_date'] = $this->_oldPackageXml['release_date']; |
} |
if (isset($this->_oldPackageXml['release_license'])) { |
$changelog['release_license'] = $this->_oldPackageXml['release_license']; |
} |
if (isset($this->_oldPackageXml['release_state'])) { |
$changelog['release_state'] = $this->_oldPackageXml['release_state']; |
} |
if (count($changelog)) { |
$this->_packageXml['changelog'] = array($changelog); |
} else { |
$this->_packageXml['changelog'] = array(); |
} |
} else { |
if (isset($this->_oldPackageXml['release_notes'])) { |
$oldchangelog['release_notes'] = $this->_oldPackageXml['release_notes']; |
} |
if (isset($this->_oldPackageXml['version'])) { |
$oldchangelog['version'] = $this->_oldPackageXml['version']; |
} |
if (isset($this->_oldPackageXml['release_date'])) { |
$oldchangelog['release_date'] = $this->_oldPackageXml['release_date']; |
} |
if (isset($this->_oldPackageXml['release_license'])) { |
$oldchangelog['release_license'] = $this->_oldPackageXml['release_license']; |
} |
if (isset($this->_oldPackageXml['release_state'])) { |
$oldchangelog['release_state'] = $this->_oldPackageXml['release_state']; |
} |
} |
$hasoldversion = false; |
foreach($this->_packageXml['changelog'] as $index => $changelog) { |
if ($oldchangelog && isset($oldchangelog['version']) |
&& strnatcasecmp($oldchangelog['version'], $changelog['version']) == 0) { |
$hasoldversion = true; |
} |
if (isset($changelog['version']) && strnatcasecmp($changelog['version'], $this->_options['version']) == 0) { |
$curlog = $index; |
} |
if (isset($this->_packageXml['changelog'][$index]['release_notes'])) { |
$this->_packageXml['changelog'][$index]['release_notes'] = trim($changelog['release_notes']); |
} |
// the parsing of the release notes adds a \n for some reason |
} |
if (!$hasoldversion && $oldchangelog && count($oldchangelog) |
&& $oldchangelog['version'] != $this->_options['version']) { |
$this->_packageXml['changelog'][] = $oldchangelog; |
} |
$notes = ($this->_options['changelognotes'] ? |
$this->_options['changelognotes'] : $this->_options['notes']); |
$changelog = array('version' => $this->_options['version'], |
'release_date' => date('Y-m-d'), |
'release_license' => $this->_options['license'], |
'release_state' => $this->_options['state'], |
'release_notes' => $notes, |
); |
if ($curlog !== false) { |
$this->_packageXml['changelog'][$curlog] = $changelog; |
} else { |
$this->_packageXml['changelog'][] = $changelog; |
} |
usort($this->_packageXml['changelog'], array($this, '_changelogsort')); |
} |
|
/** |
* @static |
* @access private |
*/ |
function _changelogsort($a, $b) |
{ |
if ($this->_options['changelogoldtonew']) { |
$c = strtotime($a['release_date']); |
$d = strtotime($b['release_date']); |
$v1 = $a['version']; |
$v2 = $b['version']; |
} else { |
$d = strtotime($a['release_date']); |
$c = strtotime($b['release_date']); |
$v2 = $a['version']; |
$v1 = $b['version']; |
} |
if ($c - $d > 0) { |
return 1; |
} elseif ($c - $d < 0) { |
return -1; |
} |
return version_compare($v1, $v2); |
} |
|
/** |
* @return true|PEAR_Error |
* @uses _generateNewPackageXML() if no package.xml is found, it |
* calls this to create a new one |
* @param string full path to package file |
* @param string name of package file |
* @throws PEAR_PACKAGEFILEMANAGER_PATH_DOESNT_EXIST |
* @access private |
*/ |
function _getExistingPackageXML($path, $packagefile = 'package.xml') |
{ |
if (is_string($path) && is_dir($path)) { |
$contents = false; |
if (file_exists($path . $packagefile)) { |
$contents = file_get_contents($path . $packagefile); |
} |
if (!$contents) { |
return $this->_generateNewPackageXML(); |
} else { |
$PEAR_Common = $this->_options['pearcommonclass']; |
if (!class_exists($PEAR_Common)) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS); |
} |
$common = new $PEAR_Common; |
if (is_a($common, 'PEAR_Common')) { |
$this->_oldPackageXml = |
$this->_packageXml = $common->infoFromString($contents); |
} else { // new way |
require_once 'PEAR/PackageFile.php'; |
$z = &PEAR_Config::singleton(); |
$pkg = &new PEAR_PackageFile($z); |
$pf = &$pkg->fromXmlString($contents, PEAR_VALIDATE_DOWNLOADING, $path . $packagefile); |
if (PEAR::isError($pf)) { |
return $pf; |
} |
if ($pf->getPackagexmlVersion() != '1.0') { |
return PEAR::raiseError('PEAR_PackageFileManager can only manage ' . |
'package.xml version 1.0, use PEAR_PackageFileManager_v2 for newer' . |
' package files'); |
} |
$this->_oldPackageXml = |
$this->_packageXml = $pf->toArray(); |
} |
if (PEAR::isError($this->_packageXml)) { |
return $this->_packageXml; |
} |
if ($this->_options['cleardependencies']) { |
$this->_packageXml['release_deps'] = $this->_options['deps']; |
} |
if ($this->_options['deps'] !== false) { |
$this->_packageXml['release_deps'] = $this->_options['deps']; |
} else { |
if (isset($this->_packageXml['release_deps'])) { |
$this->_options['deps'] = $this->_packageXml['release_deps']; |
} |
} |
if ($this->_options['maintainers'] !== false) { |
$this->_packageXml['maintainers'] = $this->_options['maintainers']; |
} else { |
$this->_options['maintainers'] = $this->_packageXml['maintainers']; |
} |
unset($this->_packageXml['filelist']); |
unset($this->_packageXml['provides']); |
} |
return true; |
} else { |
if (!is_string($path)) { |
$path = gettype($path); |
} |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_PATH_DOESNT_EXIST, |
$path); |
} |
} |
|
/** |
* Create the structure for a new package.xml |
* |
* @uses $_packageXml emulates reading in a package.xml |
* by using the package, summary and description |
* options |
* @return true|PEAR_Error |
* @access private |
*/ |
function _generateNewPackageXML() |
{ |
$this->_oldPackageXml = false; |
if (!isset($this->_options['package'])) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOPACKAGE); |
} |
if (!isset($this->_options['summary'])) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOSUMMARY); |
} |
if (!isset($this->_options['description'])) { |
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NODESC); |
} |
$this->_packageXml = array(); |
$this->_packageXml['package'] = $this->_options['package']; |
$this->_packageXml['summary'] = $this->_options['summary']; |
$this->_packageXml['description'] = $this->_options['description']; |
$this->_packageXml['changelog'] = array(); |
if ($this->_options['deps'] !== false) { |
$this->_packageXml['release_deps'] = $this->_options['deps']; |
} else { |
$this->_packageXml['release_deps'] = $this->_options['deps'] = array(); |
} |
if ($this->_options['maintainers'] !== false) { |
$this->_packageXml['maintainers'] = $this->_options['maintainers']; |
} else { |
$this->_packageXml['maintainers'] = $this->_options['maintainers'] = array(); |
} |
return true; |
} |
} |
|
if (!function_exists('file_get_contents')) { |
/** |
* @ignore |
*/ |
function file_get_contents($path, $use_include_path = null, $context = null) |
{ |
$a = @file($path, $use_include_path, $context); |
if (is_array($a)) { |
return implode('', $a); |
} else { |
return false; |
} |
} |
} |
?> |