getChildren() as $child) { $mf = self::createFromSdlTag($child); $ret[] = $mf; } return $ret; } /** * Build a manifest from a SdlTag * * @return Manifest The manifest */ public static function createFromSdlTag(SdlTag $tag) { $mf = new Manifest(); // Output $mf->setOutput($tag->getValue()); foreach ($tag->getChildren() as $child) switch ($child->getTagName()) { case 'library': $val = $child->getValue(); if ($val === null) $val = true; $mf->setIsLibrary($val); break; case 'compress': $val = $child->getValue(); if ($val === null) $val = true; $mf->setCompression($val); break; case 'verbatim': $val = $child->getValue(); if ($val === null) $val = true; $mf->setVerbatim($val); break; case 'stub': $mf->setStubFile($child->getValue()); break; case 'include': foreach ($child->getChildren() as $inc) switch ($inc->getTagName()) { case 'dir': case 'file': $mf->addSource($inc->getTagName(),$inc->getValue(),$inc->getAttributeStrings()); break; } break; case 'exclude': foreach ($child->getChildren() as $inc) switch ($inc->getTagName()) { case 'dir': $val = (string)$inc->getValue(); $mf->excludes[] = "*/{$val}/*"; break; case 'file': $val = (string)$inc->getValue(); $mf->excludes[] = "*/{$val}"; break; } break; case 'metadata': foreach ($child->getChildren() as $meta) { if (($prop = $meta->getAttribute("prop"))) { if (array_key_exists($prop,$mf->props)) { $value = $mf->props[$prop]; } else { log_warn("Property %s is not defined", $prop); } } else { $value = $meta->getValue(); } $mf->setMetadata($meta->getTagName(), $value); } break; case 'props': $props = []; if ($src = (string)$child->getValue()) { if (!file_exists($src)) { log_warn("Property file %s not found", $src); continue; } log_info("Reading props from file %s", $src); $props = file($src, FILE_SKIP_EMPTY_LINES|FILE_IGNORE_NEW_LINES); } elseif ($script = (string)$child->getAttribute('exec')) { log_info("Generating props using %s", $script); if (fnmatch("*.php",$script)) $script = "php {$script}"; exec($script, $props, $ret); if ($ret>0) { log_warn("Script exited with code %d", $ret); continue; } } else { log_warn("Props specified without either script or src. Properties will not be added."); continue; } foreach ($props as $prop) { $prop = trim($prop); // skip comments and empty lines if ($prop && $prop[0]=='#') continue; if (strpos($prop,'=')===false) continue; // extract key/value list ($k,$v) = explode("=",$prop,2); log_debug(" prop[%s] = %s", strtoupper($k),$v); $mf->props[strtoupper($k)] = $v; } break; } return $mf; } public function setOutput($output) { $this->output = $output; return $this; } public function getOutput() { return $this->output; } public function setIsLibrary($value) { $this->library = (bool)$value; return $this; } public function getIsLibrary() { return $this->library; } public function setStubFile($file) { $this->stub = $file; return $this; } public function getStubFile() { return $this->stub; } public function setMetadata($key,$value) { $this->metadata[$key] = $value; } public function getMetadata($key=null) { if ($key===null) return $this->metadata; if (!array_key_exists($key, $this->metadata)) return null; return $this->metadata[$key]; } public function setCompression($value) { $this->compress = $value; return $this; } public function getCompression() { return $this->compress; } public function setVerbatim($value) { $this->verbatim = $value; return $this; } public function getVerbatim() { return $this->verbatim; } public function addSource($type, $path, array $opts) { $this->sources[] = (object)[ 'type' => $type, 'path' => $path, 'opts' => (object)$opts, ]; return $this; } public function getSources() { return $this->sources; } public function findSourceFiles() { $items = []; foreach ($this->sources as $source) { if (@isset($source->opts->verbatim)) { $verbatim = $source->opts->verbatim; } else { $verbatim = $this->getVerbatim(); } if ($source->type == 'dir') { $it = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($source->path)); foreach ($it as $item) { if ($item->isDir()) continue; $items[] = (object)['src'=>realpath($item->getPathname()),'dest'=>$item->getPathname(),'verbatim'=>$verbatim]; } } elseif ($source->type == 'file') { $items[] = (object)['src'=>realpath($source->path),'dest'=>$source->path,'verbatim'=>$verbatim]; } else { log_warn("Unsupported source type: %s", $source->type); } } $rules = $this->excludes; $before = count($items); $items = array_filter($items, function ($item) use ($rules) { foreach ($rules as $rule) { if (fnmatch($rule, $item->src)) return false; } return true; }); $after = count($items); if ($after < $before) { log_debug("Skipped %d files matching exclusion patterns", $before-$after); } return $items; } public function getProps() { return (array)$this->props; } }