From 02b91d354e1b212418d8c512592d34e723b6126a Mon Sep 17 00:00:00 2001 From: Steve Dibb Date: Tue, 15 Dec 2009 20:49:23 +0000 Subject: git-svn-id: file:///var/svn/portage@2 3218660a-b0cf-4799-a991-8ddcc5b9e0f3 --- class.portage.atom.php | 67 +++++ class.portage.category.php | 54 ++++ class.portage.ebuild.php | 494 ++++++++++++++++++++++++++++++++++++ class.portage.license.php | 45 ++++ class.portage.package.changelog.php | 65 +++++ class.portage.package.mask.php | 38 +++ class.portage.package.php | 150 +++++++++++ class.portage.tree.php | 154 +++++++++++ class.portage.use_flag.php | 38 +++ 9 files changed, 1105 insertions(+) create mode 100644 class.portage.atom.php create mode 100644 class.portage.category.php create mode 100644 class.portage.ebuild.php create mode 100644 class.portage.license.php create mode 100644 class.portage.package.changelog.php create mode 100644 class.portage.package.mask.php create mode 100644 class.portage.package.php create mode 100644 class.portage.tree.php create mode 100644 class.portage.use_flag.php diff --git a/class.portage.atom.php b/class.portage.atom.php new file mode 100644 index 0000000..8062d0d --- /dev/null +++ b/class.portage.atom.php @@ -0,0 +1,67 @@ + + private $lt; // lesser than < + private $eq; // equals = + private $ar; // any revision ~ + private $av; // any version * + + private $arr_chars; + private $arr_ranges; + + public $ebuild_atom; + + function __construct($str) { + + $this->gt = false; + $this->lt = false; + $this->eq = false; + $this->ar = false; + $this->av = false; + + // Find the ranges + if($str[0] == '>') + $this->gt = true; + + if($str[0] == '<') + $this->lt = true; + + if($str[0] == '=' || $str[1] == '=') + $this->eq = true; + + if($str[0] == '~') + $this->ar = true; + + $end = $str[strlen($str) - 1]; + + if($end == '*') + $this->av = true; + + $this->arr_chars = array('>', '<', '=', '~', '*'); + + foreach($this->arr_chars as $char) + $str = str_replace($char, '', $str); + + $this->arr_ranges = array('gt', 'lt', 'eq', 'ar', 'av'); + + $this->ebuild_atom = $str; + + + parent::__construct($this->ebuild_atom); + + } + + function __get($str) { + + if(in_array($str, $this->arr_ranges)) + return $this->$str; + else + return parent::__get($str); + } + + } + +?> \ No newline at end of file diff --git a/class.portage.category.php b/class.portage.category.php new file mode 100644 index 0000000..5f4c193 --- /dev/null +++ b/class.portage.category.php @@ -0,0 +1,54 @@ +setCategory($str); + + } + + public function __get($var) { + return $this->$var; + } + + public function __toString() { + return $this->name; + } + + protected function setCategory($str) { + + $str = basename($str); + $dir = $this->getTree()."/".$str; + + if(is_dir($dir)) { + $this->name = $str; + $this->dir = $dir; + + $scandir = scandir($this->dir); + $scandir = preg_grep('/^\.{1,2}$/', $scandir, PREG_GREP_INVERT); + + foreach($scandir as $name) + if(is_dir($this->dir."/".$name)) + $arr[] = $name; + + sort($arr); + + $this->arr_packages = $arr; + + } + + } + + public function getPackages() { + return $this->arr_packages; + } + + } +?> \ No newline at end of file diff --git a/class.portage.ebuild.php b/class.portage.ebuild.php new file mode 100644 index 0000000..d96f46a --- /dev/null +++ b/class.portage.ebuild.php @@ -0,0 +1,494 @@ +atom = trim($str); + $this->arr_suffix = array('alpha', 'beta', 'rc', 'pre', 'p'); + $this->portage = '/usr/portage'; + $this->cache = $this->portage.'/metadata/cache'; + + $this->has_version = $this->hasVersion(); + + $this->filename = $this->portage."/".$this->getCategory()."/".$this->getPackageName()."/".$this->getFullPackageName().".ebuild"; + + $this->filename_cache = $this->cache."/".$this->getCategory()."/".$this->getFullPackageName(); + + + $this->arr_metadata_keys = array('depend', 'rdepend', 'slot', 'src_uri', 'restrict', 'homepage', 'license', 'description', 'keywords', 'inherited', 'iuse', 'cdepend', 'pdepend', 'provide', 'eapi', 'properties', 'defined_phases'); + + + + // Run this first to check if it has a version or not +// $this->getPackageName(); + + } + + public function __get($var) { + + if(is_null($this->$var)) { + + if(in_array($var, $this->arr_metadata_keys)) { + + if(is_null($this->arr_metadata)) + $this->arr_metadata = $this->metadata(); + return $this->arr_metadata[$var]; + } + + switch($var) { + + // Suffixes + case 'version': + case '_alpha': + case '_beta': + case '_pre': + case '_rc': + case '_p': + return $this->getSuffix($var); + + // 'r' is the only one that could + // get a bit confusing, since there's so many + // other ways to get these. + // 'pr' is the correct way, since portage + // has a stored variable for it. + case 'pr': + case 'r': + case '_r': + case 'revision': + return $this->getSuffix('pr'); + break; + + // Other + case 'category': + return $this->getCategory(); + break; + + case 'slot': + return $this->getSlot(); + break; + + // Ebuild Variables + case 'p': + return $this->getPackageNameAndVersionMinusRevision(); + break; + + case 'pn': + case 'package': + return $this->getPackageName(); + break; + + case 'pf': + return $this->getFullPackageName(); + break; + + case 'pv': + return $this->getPackageVersionMinusRevision(); + break; + + case 'pvr': + return $this->getPackageVersionAndRevision(); + break; + + case 'mtime': + return $this->getMtime(); + break; + + case 'filename': + return $this->filename; + break; + + } + + } + + return $this->$var; + } + + /** + * Gather information about the ebuild + * from the metadata cache + * + * Line item reference: + * + * 0. DEPEND + * 1. RDEPEND + * 2. SLOT + * 3. SRC_URI + * 4. RESTRICT + * 5. HOMEPAGE + * 6. LICENSE + * 7. DESCRIPTION + * 8. KEYWORDS + * 9. INHERITED (eclasses) + * 10. IUSE + * 11. CDEPEND (always empty) + * 12. PDEPEND + * 13. PROVIDE + * 14. EAPI + * 15. PROPERTIES + * 16. DEFINED_PHASES (functions called) + * 17. - 21. unused + * + */ + function metadata() { + + if(!is_null($this->arr_metadata)) + return $this->arr_metadata; + + if(!file_exists($this->filename)) + return array(); + + $file = file($this->filename_cache, FILE_IGNORE_NEW_LINES); + + // Kill off the empty lines + $arr = array_slice($file, 0, 17, true); + + $arr = array_combine($this->arr_metadata_keys, $arr); + + return $arr; + + } + + + function getCategory() { + + $var = 'category'; + + $arr = explode("/", $this->atom); + + if(!count($arr) || count($arr) == 1) + $this->$var = null; + else { + + // Old code from another class, for reference +// $atom = preg_replace('/^!?[><]?=?~?/', '', $atom); +// $tmp = explode('/', $atom); + + $str = current($arr); +// $str = preg_replace("/[^a-z_-]/", "", $str); + $this->$var = $str; + } + + return $this->$var; + + } + + function getFullPackageName() { + + $var = 'pf'; + + if($this->has_version) + return $this->$var = $this->getPackageName()."-".$this->getPackageVersionAndRevision(); + else + return ""; + + } + + function getMajorVersion() { + $this->getComponents(); + $arr = explode(".", $this->version); + return $arr[0]; + } + + function getMinorVersion() { + $this->getComponents(); + $arr = explode(".", $this->version); + return $arr[1]; + } + + function getPackageName() { + +// $var = 'pn'; +// +// $str = $this->stripCategory(); +// $str = $this->stripSlot($str); +// +// // Will only return the package name +// $pattern = '/\-\d+((\.?\d+)+)?([A-Za-z]+)?((_(alpha|beta|pre|rc|p)\d*)+)?(\-r\d+)?(\:.+)?$/'; +// $arr = preg_split($pattern, $str); +// +// // Check to see if it has a version or not (p.mask) +// if(count($arr) == 1) +// $this->has_version = false; +// +// $this->$var = $arr[0]; +// +// return $this->$var; + + + return $this->pn; + + } + + function getPackageNameAndVersionMinusRevision() { + + $arr = $this->getComponents(); + + return $this->p = $this->getPackageName."-".$arr['pv']; + } + + function getPackageVersionMinusRevision() { + + $var = 'pv'; + + if(!$this->has_version) + return $this->$var = ""; + + $arr = $this->getComponents(); + + $str = $arr['version']; + + foreach($this->arr_suffix as $tmp) { + + if(!is_null($arr[$tmp])) { + + // Can't use empty, since it will break on + // _suffix0 + if(strlen($arr[$tmp]) == 0) + $str .= "_$tmp"; + else + $str .= "_$tmp".$arr[$tmp]; + } + } + + return $this->$var = $str; + + } + + function getPackageVersionAndRevision() { + + $var = 'pvr'; + + if(!$this->has_version) + return $this->$var = ""; + + $arr = $this->getComponents(); + + $str = $this->getPackageVersionMinusRevision(); + + if($arr['r']) + $str .= "-r".$arr['r']; + return $this->$var = $str; + } + + function getSlot() { + + $var = 'slot'; + + if(strpos($this->atom, ':') > 0) { + $str = end(explode(':', $this->atom)); + } + else + $str = 0; + + $this->$var = $str; + + return $this->$var; + + } + + // This could really use a better name. + function getSuffix($var) { + + if(in_array($var, array('_alpha', '_beta', '_pre', '_rc', '_p', 'pr', 'version'))) { + $arr = $this->getComponents(); + if($var[0] == "_") + $str = str_replace("_", "", $var); + return $this->$var = $arr[$str]; + } + + } + + /** + * Simplified way to get specific version information + */ + function getComponents() { + + $arr_components = array(); + + if(count($this->arr_components)) { + return $this->arr_components; + } + + if(!$this->has_version) + return array('version' => '', 'pv' => ''); + + $str = $this->stripPackage($str); + + $arr = explode("-", $str); + + // We might be done at this point, depending on + // the details of the atom passed in. + if(!count($arr)) + return $this->arr_components = $arr_components; + + $arr_components['pv'] = array_shift($arr); + + // Have the exploded one first so the version is the first value + $arr = array_merge(explode("_", $arr_components['pv']), $arr); + + // This format of the version isn't used in portage anywhere, + // but it could be useful for package.masks or something + // similar. It's basically the version without any of the + // suffices. (vim-6.3_beta3 => 6.3) + $arr_components['version'] = $this->version = array_shift($arr); + + // See if we have more + if(count($arr)) { + + foreach($arr as $str) { + + // Each value is returned as a trimmed string *if* it + // can find that there is a suffix version of it. The + // reason for this is because there are three possible + // outcomes: the value is not set (null), it is set, but + // there is no number (empty string), or it has a value + // (integer). + + if(substr($str, 0, 5) == "alpha") + $arr_components['alpha'] = $this->_alpha = trim(substr($str, 5)); + elseif(substr($str, 0, 4) == "beta") + $arr_components['beta'] = $this->_beta = trim(substr($str, 4)); + elseif(substr($str, 0, 3) == "pre") + $arr_components['pre'] = $this->_pre = trim(substr($str, 3)); + elseif(substr($str, 0, 2) == "rc") + $arr_components['rc'] = $this->_rc = trim(substr($str, 2)); + // Shouldn't need the extra checks for pre/rc since the + // whole thing is going to look at each string once, and + // in order .. but weirder things have happened. More + // checks never hurt. + elseif($str[0] == "p" && !(substr($str, 0, 3) == "pre")) + $arr_components['p'] = $this->_p = trim(substr($str, 1)); + elseif($str[0] == "r" && !(substr($str, 0, 2) == "rc")) + $arr_components['r'] = $this->pr = trim(substr($str, 1)); + + } + } + + return $this->arr_components = $arr_components; + + } + + function hasVersion() { + + $str = $this->stripCategory(); + $str = $this->stripSlot($str); + + // Same pattern as in getPackageName() + $pattern = '/\-\d+((\.?\d+)+)?([A-Za-z]+)?((_(alpha|beta|pre|rc|p)\d*)+)?(\-r\d+)?(\:.+)?$/'; + $arr = preg_split($pattern, $str); + + $this->pn = $arr[0]; + + // Check to see if it has a version or not (p.mask) + if(count($arr) == 1) { + $this->version = ""; + $this->pf = ""; + $this->pv = ""; + $this->pvr = ""; + return false; + } else + return true; + + } + + function stripCategory() { + + if(strpos($this->atom, '/') > 0) { + $arr = explode("/", $this->atom); + + if(count($arr) > 1) { + $str = $arr[1]; + } + + return $str; + } else { + return $this->atom; + } + } + + function stripPackage($str) { + + $str = $this->stripCategory(); + $str = $this->stripSlot($str); + $str = str_replace($this->getPackageName()."-", "", $str); + return $str; + + } + + function stripSlot($str) { + + if(!is_null($this->getSlot())) { + $str = str_replace(":".$this->getSlot(), "", $str); + } else + $str =& $this->atom; + + return $str; + + } + + function getMtime() { + + if(file_exists($this->filename)) + return filemtime($this->filename); + else + return null; + + } + + } + +?> \ No newline at end of file diff --git a/class.portage.license.php b/class.portage.license.php new file mode 100644 index 0000000..f269181 --- /dev/null +++ b/class.portage.license.php @@ -0,0 +1,45 @@ +setLicense($license); + + } + + public function setLicense($str) { + + $str = basename($str); + + if(file_exists($this->getTree()."/licenses/$str")) { + + if(substr($str, -4, 4) == ".pdf") { + $this->name = basename($str, ".pdf"); + $this->pdf = true; + } else { + $this->name = $str; + $this->pdf = false; + } + + } + + } + + public function getName() { + return $this->name; + } + + public function isPDF() { + return $this->pdf; + } + + + } +?> \ No newline at end of file diff --git a/class.portage.package.changelog.php b/class.portage.package.changelog.php new file mode 100644 index 0000000..bdadbb5 --- /dev/null +++ b/class.portage.package.changelog.php @@ -0,0 +1,65 @@ +changelog = $str; + + if(!is_null($date)) + $this->date = $date; + + } + + + function getRecentChanges() { + + $pattern_date = "/^\d{1,2}\s\w{3}\s\d{4}/"; +// $pattern_dev = "/<\w+@gentoo\.org>/"; + + $arr = explode("\n", $this->changelog); +// print_r($arr); + + // Cut off the header + $arr = array_slice($arr, 4); + + // Get the date of the latest changes + $str = trim($arr[0]); + + preg_match_all($pattern_date, $str, $matches); + $this->recent_date = $date = current(current($matches)); + + $start = false; + + $recent_changes = ""; + + foreach($arr as $str) { + + $first_char = substr($str, 0, 1); + $last_char = substr($str, -1, 1); + + if(($first_char == "*" || empty($str)) && $start) { + break; + } + + if($start) { + $recent_changes .= " ".trim($str); + } + + if($last_char == ":") { + $start = true; + } + + } + + return $recent_changes; + + } + + + } + +?> \ No newline at end of file diff --git a/class.portage.package.mask.php b/class.portage.package.mask.php new file mode 100644 index 0000000..88936cb --- /dev/null +++ b/class.portage.package.mask.php @@ -0,0 +1,38 @@ +filename = $this->getTree()."/profiles/$filename"; + + } + + function getMaskedPackages() { + + $arr = file($this->filename, FILE_IGNORE_NEW_LINES); + + $arr = preg_grep("/(^#|^$)/", $arr, PREG_GREP_INVERT); + + sort($arr); + + return $arr; + + } + + } + +?> \ No newline at end of file diff --git a/class.portage.package.php b/class.portage.package.php new file mode 100644 index 0000000..c974949 --- /dev/null +++ b/class.portage.package.php @@ -0,0 +1,150 @@ +setPackage($category, $package); + + } + + public function __get($var) { + return $this->$var; + } + + public function __toString() { + return $this->name; + } + + private function setPackage($category, $package) { + + parent::setCategory($category); + + $package = basename($package); + $dir = $this->dir."/".$package; + + if(is_dir($dir)) { + $this->name = $package; + + $scandir = scandir($dir); + $arr = preg_grep('/\.ebuild$/', $scandir); + $arr = preg_replace("/\.ebuild$/", "", $arr); + + sort($arr); + + $this->arr_ebuilds = $arr; + + } + + if(file_exists("$dir/metadata.xml")) { + $this->metadata_filename = "$dir/metadata.xml"; + $this->metadata_xml = simplexml_load_file($this->metadata_filename); + } + + if(file_exists("$dir/ChangeLog")) { + $this->changelog_filename = "$dir/ChangeLog"; + $str = file_get_contents($this->changelog_filename); + $str = trim($str); + $this->changelog = $str; + } + + } + + public function getCategory() { + return parent::getName(); + } + + public function getEbuilds() { + return $this->arr_ebuilds; + } + + public function getHerds() { + + $arr = array(); + + if(!$this->metadata_filename) + return $arr; + + if(!$this->metadata_xml) + $this->metadata_xml = simplexml_load_file($this->metadata_filename); + + if($this->metadata_xml->herd) { + foreach($this->metadata_xml->herd as $name) { + $arr[] = (string)$name; + } + } + + sort($arr); + + return $arr; + + } + + public function getMaintainers() { + + $arr = array(); + + if(!$this->metadata_filename) + return $arr; + + if(!$this->metadata_xml) + $this->metadata_xml = simplexml_load_file($this->metadata_filename); + + if($this->metadata_xml->maintainer) { + $x = 0; + foreach($this->metadata_xml->maintainer as $maintainer) { + if($maintainer->name) + $arr[$x]['name'] = (string)$maintainer->name; + if($maintainer->email) + $arr[$x]['email'] = (string)$maintainer->email; + $x++; + } + } + + return $arr; + + } + + public function getUseFlags() { + + $arr = array(); + + if(!$this->metadata_filename) + return $arr; + + if(!$this->metadata_xml) + $this->metadata_xml = simplexml_load_file($this->metadata_filename); + + // Getting attributes is always a pain + // http://us.php.net/manual/en/function.simplexml-element-attributes.php + if($this->metadata_xml->use) { + foreach($this->metadata_xml->use->flag as $flag) { + foreach($flag->attributes() as $key => $name) { + if($key == 'name') { + $name = (string)$name; + $arr[$name] = (string)$flag; + } + } + } + } + ksort($arr); + return $arr; + + } + + } +?> \ No newline at end of file diff --git a/class.portage.tree.php b/class.portage.tree.php new file mode 100644 index 0000000..4cb17da --- /dev/null +++ b/class.portage.tree.php @@ -0,0 +1,154 @@ +setTree($tree); + } + + function getTree() { + return $this->tree; + } + + function setTree($x) { + if(is_string($x) && is_dir($x)) + $this->tree = $x; + } + + function getArches($prefix = false) { + + $filename = $this->getTree().'/profiles/arch.list'; + $arr = file($filename, FILE_IGNORE_NEW_LINES); + + $barrier = key(preg_grep("/^\s*$/", $arr)); + + if($prefix) { + $arr = array_slice($arr, $barrier); + } else { + $arr = array_slice($arr, 0, $barrier); + } + + $arr = preg_grep('/^[a-z]/', $arr); + sort($arr); + + foreach($arr as $value) { + $arches[] = $value; + } + + return $arches; + + } + + public function getCategories() { + + $filename = $this->getTree().'/profiles/categories'; + $arr = file($filename, FILE_IGNORE_NEW_LINES); + + $arr = preg_grep('/^[a-z]/', $arr); + sort($arr); + + foreach($arr as $value) { + $categories[] = $value; + } + + return $categories; + + } + + public function getEclasses() { + + $scandir = scandir($this->getTree().'/eclass/'); + + $scandir = preg_grep('/\.eclass$/', $scandir); + sort($scandir); + foreach($scandir as $filename) { + $filename = preg_replace("/\.eclass$/", "", $filename); + $arr[] = $filename; + } + + $this->arr_eclasses = $arr; + + return $arr; + + } + + function getLicenses() { + + $scandir = scandir($this->getTree().'/licenses/'); + $scandir = preg_grep('/^\.{1,2}$/', $scandir, PREG_GREP_INVERT); + sort($scandir); + foreach($scandir as $filename) { + $arr[] = $filename; + } + + $this->arr_licenses = $arr; + + return $arr; + + } + + /** Use Flags **/ + + /** + * Get the use flags for any file w/use flags + * + * @param filename filename of use flags + * @return array + */ + protected function arrUseFlags($filename) { + + $arr_file = file($filename, FILE_IGNORE_NEW_LINES); + + $arr_file = preg_grep('/^.+\s+\-\s+/', $arr_file); + + sort($arr_file); + + foreach($arr_file as $str) { + $arr = explode(' - ', $str); + $desc = str_replace($arr[0].' - ', '', $str); + $arr_use_flags[$arr[0]] = $desc; + } + + return $arr_use_flags; + } + + /** + * Get the global use flags + * + */ + public function getUseFlags() { + return array_keys($this->arrUseFlags($this->getTree()."/profiles/use.desc")); + } + + /** + * Create an array of the current list of herds + * + * @return array + */ + function getHerds() { + + $arr = array(); + + $filename = $this->getTree().'/metadata/herds.xml'; + + if(file_exists($filename)) { + $obj_xml = simplexml_load_file($filename); + + foreach($obj_xml->herd as $obj) { + $herd = (string)$obj->name; + $arr[] = $herd; + } + sort($arr); + } + return $arr; + } + + } +?> \ No newline at end of file diff --git a/class.portage.use_flag.php b/class.portage.use_flag.php new file mode 100644 index 0000000..9be0497 --- /dev/null +++ b/class.portage.use_flag.php @@ -0,0 +1,38 @@ +arr_use_flags = $this->arrUseFlags($this->getTree()."/profiles/use.desc"); + + if($str) + $this->setFlag($str); + + } + + private function setFlag($str) { + if($this->arr_use_flags[$str]) + $this->name = $str; + } + + public function getName() { + return $this->name; + } + + public function getDescription() { + return $this->arr_use_flags[$this->getName()]; + } + + + } +?> \ No newline at end of file -- cgit v1.2.3-65-gdbad