[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
A usefull tool (Was: Making Fedora Core CD #1 Standalone)
- From: Chris Chabot <chabotc 4-ice com>
- To: Development discussions related to Fedora Core <fedora-devel-list redhat com>, rpm-list redhat com
- Cc:
- Subject: A usefull tool (Was: Making Fedora Core CD #1 Standalone)
- Date: Tue, 25 May 2004 16:06:40 +0200
Dep Tree 0.1 by Chris Chabot.
This program may be freely redistributed under the terms of the GNU GPL.
With all these discussions about making Fedora Core a core cd, ideas
about what should or should not be included, i thought it might be easy
to be able to quantify and experiment with package dependencies and
package sizes so you can find out what can and can not fit on one CD.
This script takes a package or list of packages as command line
argument, and recursivly walks the full dependency tree for that/those
package(s) and calculates the packages size (size of the RPM's) and
installed size (size on disk) for the packages.
It queries the rpm database using the rpm command line tool, so please
only use the base package name (mozilla) and not the file name
(mozilla-1.6-6.i386.rpm). Also note that since this tool only queries
the rpm database, and doesn't write or change anything, so safe to play
around with.
For example
# ./dep-tree.php mozilla
<.. shows the complete tree of all the dep. packages & package sizes..>
Number of packages: 66
Total size installed: 165 Mb
Total packaged size: 59 Mb
With this tool it's a lot easier to experiment with 'what if', and try
out what the real impact is of including package XYZ in the core CD.
It can also take multiple packages on the command line, and will do a
full dependency tree run for all those packages, so you could see how
many packages, and what packaged size something like the packages
"firstboot system-config-packages mozilla" would take up..
This script requires PHP and RPM to be installed to run. Save the
attached dep-tree.php to disk and run by
# chmod +x dep-tree.php
# ./dep-tree.php
or
# php -Cq ./dep-tree.php
Usage explained in detail: dep-tree.php [-d] [-r=path] package [package
package]
package [package..] List of packages to include in the dependency
tree run, for example: "mozilla openoffice.org sendmail"
-d Include the *-devel packages for all packages in the list
(and it's dependencies). This is includes because i am a big fan of
having a system that could build it's self, it's updates and any other
source rpm's/tarbals you would download.
-r=/path (For users who know what they are doing only!) Use
--root=/path in all rpm commands. The rpm --root command allows you to
query against a rpm database other then the standard location. This is
usefull for if you want to play with all installed packages or packages
you don't have installed in your normal setup without having to modify
your existing setup by doing something like this (Note: Please please by
all that is holy, don't forget to include --root=/fc2-tests in your rpm
--initdb command, else you will NUKE, DELETE and DESTROY your rpm database!)
# mkdir /fc2-test
# rpm --initdb --root=/fc2-test
# rpm -Uvh --root=/fc2-test --nomd5 --nodigest --nosignature --justdb
/location/to/all/fc2/rpms/*.rpm
#!/usr/bin/php -Cq
<?
// Written by Chris Chabot
// Published under the GNU GPL for licence
// You know what it is and where to find it..
function usage()
{
global $argv;
echo "Usage: {$argv[0]} [-d] [-r=path] package [package package]\n\n".
" -r=path (optional): Use this for RPM's --root\n".
" -d (optional): Include devel package(s)\n".
" package Name of installed package(s)\n".
"\n";
exit(1);
}
function get_devel_list()
{
global $devels, $root;
$exec = "rpm -qa $root --qf \"%{NAME}\n\" | grep devel";
$output = `$exec`;
$devels = explode("\n",$output);
}
function get_sizes($package)
{
global $size_installed, $size_packages, $root;
$exec = "rpm -q $root --qf \"%{SIZE} %{SIGSIZE}\" ".escapeshellarg($package);
$output = `$exec`;
$sizes = explode(' ',$output);
if (isset($sizes[0]) && is_numeric($sizes[0])) {
$size_installed += (int) $sizes[0];
}
if (isset($sizes[1]) && is_numeric($sizes[1])) {
$size_packages += (int) $sizes[1];
echo " (".ceil($sizes[1] / 1024)." Kb)";
}
}
function what_provides($p_requires)
{
global $files_done, $requires, $root;
$packages = array();
reset($p_requires);
while (list($require,) = each($p_requires)) {
// Check if require has already been done
if (!isset($files_done[$require])) {
$exec = "rpm -q $root --whatprovides \"$require\" --qf \"%{NAME}\"";
$output = `$exec`;
if (strpos($output,'no package') === FALSE) {
$output = trim($output);
$packages[$output] = $output;
$files_done[$require] = $output;
} elseif (isset($files_done[$require])) {
$packages[$output] = $files_done[$require];
} else {
// echo "No package provides: \"$require\"\n";
}
}
}
return $packages;
}
function package_requires($package)
{
global $root;
$exec = "rpm -q $root --requires ".escapeshellarg($package);
$output = `$exec`;
$output = explode("\n",$output);
unset($output[count($output)-1]);
$list = array();
while (list(,$require) = each($output)) {
if (($pos = strpos($require,' ')) !== FALSE) {
$require = trim(substr($require,0,$pos));
}
// Skip internal rpmlib tags which are not 'provided'
if (!isset($list[$require]) && strpos($require,'rpmlib') === false && strpos($require,'perl') === false) {
$list[$require] = TRUE;
}
}
return $list;
}
function find_package_require($package)
{
global $requires, $level, $devel, $devels, $packages;
// Don't re-require self
$packages++;
$requires[$package] = $package;
echo str_repeat(' ',$level).$package;
get_sizes($package);
echo "\n";
$p_requires = package_requires($package);
if (count($p_requires)) {
$pkgs = what_provides($p_requires);
if (count($pkgs)) {
$level++;
reset($pkgs);
while (list(,$pkg) = each($pkgs)) {
// Skip dep's we've already done
if (!isset($requires[$pkg])) {
$requires[$pkg] = $pkg;
find_package_require($pkg);
}
}
$level--;
}
}
if ($devel) {
reset($devels);
while (list(,$pkg) = each($devels)) {
if ($pkg == $package."-devel") {
find_package_require($pkg);
break;
}
}
}
}
echo "\nDep Tree 0.1 by Chris Chabot.\nThis program may be freely redistributed under the terms of the GNU GPL.\n\n";
// Program initialisation
$requires = array();
$files_done = array();
$devels = array();
$packages = 0;
$level = 0;
$max_level = 9999;
$size_installed = 0;
$size_packages = 0;
$devel = false;
$root = '';
if ($argc < 2) {
usage();
} else {
for ($i = 1 ; $i < $argc ; $i++) {
if ($argv[$i] == '-d') {
$devel = TRUE;
get_devel_list();
} elseif (substr($argv[$i],0,2) == '-r') {
$root = substr($argv[$i],3);
if (!file_exists($root)) {
die("Invalid RPM root specified, $root doesn't exist. Aborting\n");
}
$root = " --root=$root ";
}
}
for ($i = 1 ; $i < $argc ; $i++) {
if (substr($argv[$i],0,1) != '-') {
// If package was already evaluted as dependencie, don't re-process it
if (!isset($requires[$argv[$i]])) {
find_package_require($argv[$i]);
}
}
}
}
echo "\n\n";
echo "Number of packages: $packages\n";
echo "Total size installed: ".ceil(($size_installed / 1024) / 1024)." Mb\n";
echo "Total packaged size: ".ceil(($size_packages / 1024) / 1024)." Mb\n";
echo "\n";
?>
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]