[ Index ] |
|
Code source de Symfony 1.0.0 |
1 <?php 2 /* 3 * $Id: PearPackageTask.php 3076 2006-12-18 08:52:12Z fabien $ 4 * 5 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 6 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 7 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 8 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 9 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 10 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 11 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 12 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 13 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 14 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 15 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 16 * 17 * This software consists of voluntary contributions made by many individuals 18 * and is licensed under the LGPL. For more information please see 19 * <http://phing.info>. 20 */ 21 22 require_once 'phing/tasks/system/MatchingTask.php'; 23 include_once 'phing/types/FileSet.php'; 24 25 /** 26 * A task to create PEAR package.xml file. 27 * 28 * This class uses the PEAR_PackageFileMaintainer class to perform the work. 29 * 30 * This class is designed to be very flexible -- i.e. account for changes to the package.xml w/o 31 * requiring changes to this class. We've accomplished this by having generic <option> and <mapping> 32 * nested elements. All options are set using PEAR_PackageFileMaintainer::setOptions(). 33 * 34 * The <option> tag is used to set a simple option value. 35 * <code> 36 * <option name="option_name" value="option_value"/> 37 * or <option name="option_name">option_value</option> 38 * </code> 39 * 40 * The <mapping> tag represents a complex data type. You can use nested <element> (and nested <element> with 41 * <element> tags) to represent the full complexity of the structure. Bear in mind that what you are creating 42 * will be mapped to an associative array that will be passed in via PEAR_PackageFileMaintainer::setOptions(). 43 * <code> 44 * <mapping name="option_name"> 45 * <element key="key_name" value="key_val"/> 46 * <element key="key_name" value="key_val"/> 47 * </mapping> 48 * </code> 49 * 50 * Here's an over-simple example of how this could be used: 51 * <code> 52 * <pearpkg name="phing" dir="${build.src.dir}" destFile="${build.base.dir}/package.xml"> 53 * <fileset> 54 * <include name="**"/> 55 * </fileset> 56 * <option name="notes">Sample release notes here.</option> 57 * <option name="description">Package description</option> 58 * <option name="summary">Short description</option> 59 * <option name="version" value="2.0.0b1"/> 60 * <option name="state" value="beta"/> 61 * <mapping name="maintainers"> 62 * <element> 63 * <element key="handle" value="hlellelid"/> 64 * <element key="name" value="Hans"/> 65 * <element key="email" value="hans@xmpl.org"/> 66 * <element key="role" value="lead"/> 67 * </element> 68 * </mapping> 69 * </pearpkg> 70 * </code> 71 * 72 * Look at the build.xml in the Phing base directory (assuming you have the full distro / CVS version of Phing) to 73 * see a more complete example of how to call this script. 74 * 75 * @author Hans Lellelid <hans@xmpl.org> 76 * @package phing.tasks.ext 77 * @version $Revision: 1.9 $ 78 */ 79 class PearPackageTask extends MatchingTask { 80 81 /** */ 82 private $package; 83 84 /** Base directory for reading files. */ 85 private $dir; 86 87 /** Package file */ 88 private $packageFile; 89 90 /** @var array FileSet[] */ 91 private $filesets = array(); 92 93 /** @var PEAR_PackageFileManager */ 94 private $pkg; 95 96 private $preparedOptions = array(); 97 98 /** @var array PearPkgOption[] */ 99 private $options = array(); 100 101 /** Nested <mapping> (complex options) types. */ 102 private $mappings = array(); 103 104 public function init() { 105 include_once 'PEAR/PackageFileManager.php'; 106 if (!class_exists('PEAR_PackageFileManager')) { 107 throw new BuildException("You must have installed PEAR_PackageFileManager in order to create a PEAR package.xml file."); 108 } 109 } 110 111 /** 112 * Sets PEAR package.xml options, based on class properties. 113 * @return void 114 */ 115 private function setOptions() { 116 117 // 1) first prepare/populate options 118 $this->populateOptions(); 119 120 // 2) make any final adjustments (this could move into populateOptions() also) 121 122 // default PEAR basedir would be the name of the package (e.g."phing") 123 if (!isset($this->preparedOptions['baseinstalldir'])) { 124 $this->preparedOptions['baseinstalldir'] = $this->package; 125 } 126 127 // unless filelistgenerator has been overridden, we use Phing FileSet generator 128 if (!isset($this->preparedOptions['filelistgenerator'])) { 129 if (empty($this->filesets)) { 130 throw new BuildException("You must use a <fileset> tag to specify the files to include in the package.xml"); 131 } 132 $this->preparedOptions['filelistgenerator'] = 'Fileset'; 133 $this->preparedOptions['usergeneratordir'] = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'pearpackage'; 134 // Some PHING-specific options needed by our Fileset reader 135 $this->preparedOptions['phing_project'] = $this->project; 136 $this->preparedOptions['phing_filesets'] = $this->filesets; 137 } elseif ($this->preparedOptions['filelistgeneragor'] != 'Fileset' && !empty($this->filesets)) { 138 throw new BuildException("You cannot use <fileset> element if you have specified the \"filelistgenerator\" option."); 139 } 140 141 // 3) Set the options 142 143 // No need for excessive validation here, since the PEAR class will do its own 144 // validation & return errors 145 $e = $this->pkg->setOptions($this->preparedOptions); 146 147 if (PEAR::isError($e)) { 148 throw new BuildException("Unable to set options.", new Exception($e->getMessage())); 149 } 150 } 151 152 /** 153 * Fixes the boolean in optional dependencies 154 */ 155 private function fixDeps($deps) 156 { 157 foreach (array_keys($deps) as $dep) 158 { 159 if (isset($deps[$dep]['optional']) && $deps[$dep]['optional']) 160 { 161 $deps[$dep]['optional'] = "yes"; 162 } 163 } 164 165 return $deps; 166 } 167 168 /** 169 * Adds the options that are set via attributes and the nested tags to the options array. 170 */ 171 private function populateOptions() { 172 173 // These values could be overridden if explicitly defined using nested tags 174 $this->preparedOptions['package'] = $this->package; 175 $this->preparedOptions['packagedirectory'] = $this->dir->getAbsolutePath(); 176 177 if ($this->packageFile !== null) { 178 // create one w/ full path 179 $f = new PhingFile($this->packageFile->getAbsolutePath()); 180 $this->preparedOptions['packagefile'] = $f->getName(); 181 // must end in trailing slash 182 $this->preparedOptions['outputdirectory'] = $f->getParent() . DIRECTORY_SEPARATOR; 183 $this->log("Creating package file: " . $f->__toString(), PROJECT_MSG_INFO); 184 } else { 185 $this->log("Creating [default] package.xml file in base directory.", PROJECT_MSG_INFO); 186 } 187 188 // converts option objects and mapping objects into 189 // key => value options that can be passed to PEAR_PackageFileManager 190 191 foreach($this->options as $opt) { 192 $this->preparedOptions[ $opt->getName() ] = $opt->getValue(); //no arrays yet. preg_split('/\s*,\s*/', $opt->getValue()); 193 } 194 195 foreach($this->mappings as $map) { 196 $value = $map->getValue(); // getValue returns complex value 197 198 if ($map->getName() == 'deps') 199 { 200 $value = $this->fixDeps($value); 201 } 202 203 $this->preparedOptions[ $map->getName() ] = $value; 204 } 205 } 206 207 /** 208 * Main entry point. 209 * @return void 210 */ 211 public function main() { 212 213 if ($this->dir === null) { 214 throw new BuildException("You must specify the \"dir\" attribute for PEAR package task."); 215 } 216 217 if ($this->package === null) { 218 throw new BuildException("You must specify the \"name\" attribute for PEAR package task."); 219 } 220 221 $this->pkg = new PEAR_PackageFileManager(); 222 223 $this->setOptions(); 224 225 $e = $this->pkg->writePackageFile(); 226 if (PEAR::isError($e)) { 227 throw new BuildException("Unable to write package file.", new Exception($e->getMessage())); 228 } 229 230 } 231 232 /** 233 * Used by the PEAR_PackageFileManager_PhingFileSet lister. 234 * @return array FileSet[] 235 */ 236 public function getFileSets() { 237 return $this->filesets; 238 } 239 240 // ------------------------------- 241 // Set properties from XML 242 // ------------------------------- 243 244 /** 245 * Nested creator, creates a FileSet for this task 246 * 247 * @return FileSet The created fileset object 248 */ 249 function createFileSet() { 250 $num = array_push($this->filesets, new FileSet()); 251 return $this->filesets[$num-1]; 252 } 253 254 /** 255 * Set "package" property from XML. 256 * @see setName() 257 * @param string $v 258 * @return void 259 */ 260 public function setPackage($v) { 261 $this->package = $v; 262 } 263 264 /** 265 * Sets "dir" property from XML. 266 * @param PhingFile $f 267 * @return void 268 */ 269 public function setDir(PhingFile $f) { 270 $this->dir = $f; 271 } 272 273 /** 274 * Sets "name" property from XML. 275 * @param string $v 276 * @return void 277 */ 278 public function setName($v) { 279 $this->package = $v; 280 } 281 282 /** 283 * Sets the file to use for generated package.xml 284 */ 285 public function setDestFile(PhingFile $f) { 286 $this->packageFile = $f; 287 } 288 289 /** 290 * Handles nested generic <option> elements. 291 */ 292 function createOption() { 293 $o = new PearPkgOption(); 294 $this->options[] = $o; 295 return $o; 296 } 297 298 /** 299 * Handles nested generic <option> elements. 300 */ 301 function createMapping() { 302 $o = new PearPkgMapping(); 303 $this->mappings[] = $o; 304 return $o; 305 } 306 } 307 308 309 310 /** 311 * Generic option class is used for non-complex options. 312 */ 313 class PearPkgOption { 314 315 private $name; 316 private $value; 317 318 public function setName($v) { $this->name = $v; } 319 public function getName() { return $this->name; } 320 321 public function setValue($v) { $this->value = $v; } 322 public function getValue() { return $this->value; } 323 public function addText($txt) { $this->value = trim($txt); } 324 325 } 326 327 /** 328 * Handles complex options <mapping> elements which are hashes (assoc arrays). 329 */ 330 class PearPkgMapping { 331 332 private $name; 333 private $elements = array(); 334 335 public function setName($v) { 336 $this->name = $v; 337 } 338 339 public function getName() { 340 return $this->name; 341 } 342 343 public function createElement() { 344 $e = new PearPkgMappingElement(); 345 $this->elements[] = $e; 346 return $e; 347 } 348 349 public function getElements() { 350 return $this->elements; 351 } 352 353 /** 354 * Returns the PHP hash or array of hashes (etc.) that this mapping represents. 355 * @return array 356 */ 357 public function getValue() { 358 $value = array(); 359 foreach($this->getElements() as $el) { 360 if ($el->getKey() !== null) { 361 $value[ $el->getKey() ] = $el->getValue(); 362 } else { 363 $value[] = $el->getValue(); 364 } 365 } 366 return $value; 367 } 368 } 369 370 /** 371 * Sub-element of <mapping>. 372 */ 373 class PearPkgMappingElement { 374 375 private $key; 376 private $value; 377 private $elements = array(); 378 379 public function setKey($v) { 380 $this->key = $v; 381 } 382 383 public function getKey() { 384 return $this->key; 385 } 386 387 public function setValue($v) { 388 $this->value = $v; 389 } 390 391 /** 392 * Returns either the simple value or 393 * the calculated value (array) of nested elements. 394 * @return mixed 395 */ 396 public function getValue() { 397 if (!empty($this->elements)) { 398 $value = array(); 399 foreach($this->elements as $el) { 400 if ($el->getKey() !== null) { 401 $value[ $el->getKey() ] = $el->getValue(); 402 } else { 403 $value[] = $el->getValue(); 404 } 405 } 406 return $value; 407 } else { 408 return $this->value; 409 } 410 } 411 412 /** 413 * Handles nested <element> tags. 414 */ 415 public function createElement() { 416 $e = new PearPkgMappingElement(); 417 $this->elements[] = $e; 418 return $e; 419 } 420 421 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Fri Mar 16 22:42:14 2007 | par Balluche grâce à PHPXref 0.7 |