blob: 96de458e97bf30fb46dca0cc029cbec9ef294052 [file] [log] [blame]
#!/bin/bash
# Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Print a list of installed packages
#
# This list is used by make_local_repo.sh to construct a local repository
# with only those packages.
#
# Usage:
# list_installed_packages.sh > package_list.txt
# Die on error
set -e
USAGE='usage: '"$0"' [options]
options:
-v Print verbose output.
-? Print this help.
'
# Handle command line options.
# Note: Can't use shflags, since this must run inside the rootfs image.
VERBOSE=0
# Option processing using getopts
while getopts "v?" OPTVAR
do
case $OPTVAR in
"v")
VERBOSE=1
;;
"?")
echo "$USAGE";
exit 1
;;
esac
done
shift `expr $OPTIND - 1`
# Print information on a single package
function print_deb {
# Positional parameters from calling script. :? means "fail if unset".
DEB_NAME=${1:?}
# Get the installed version of the package.
DEB_VER=`dpkg-query --show -f='${Version}' $DEB_NAME`
# Get information on package from apt-cache. Use a temporary file since
# we need to extract multiple fields.
rm -f /tmp/print_deb
apt-cache show $DEB_NAME > /tmp/print_deb
# The apt cache may have more than one version of the package available.
# For example, if the user has added another repository to
# /etc/apt/sources.list to install/upgrade packages. Use bash arrays to
# hold all the results until we can find information on the version we want.
# TODO: Is there a way to do this using only awk, so we can use /bin/sh
# instead of /bin/bash?
ALL_VER=( `grep '^Version: ' < /tmp/print_deb | awk '{print $2}'` )
ALL_PRIO=( `grep '^Priority: ' < /tmp/print_deb | awk '{print $2}'` )
ALL_SECTION=( `grep '^Section: ' < /tmp/print_deb | awk '{print $2}'` )
ALL_FILENAME=( `grep '^Filename: ' < /tmp/print_deb | awk '{print $2}'` )
rm -f /tmp/print_deb
# Find only the package version the user has installed.
NUM_VER=${#ALL_VER[@]}
FOUND_MATCH=0
for ((I=0; I<$NUM_VER; I++));
do
if [ "${ALL_VER[$I]}" = "$DEB_VER" ]
then
FOUND_MATCH=1
DEB_PRIO="${ALL_PRIO[$I]}"
DEB_SECTION="${ALL_SECTION[$I]}"
DEB_FILENAME="${ALL_FILENAME[$I]}"
fi
done
# Determine if the package filename appears to be from a locally-built
# repository (as created in build_image.sh). Use ! to ignore non-zero
# exit code, since grep exits 1 if no match.
! DEB_FILENAME_IS_LOCAL=`echo $DEB_FILENAME | grep 'local_packages'`
if [ $FOUND_MATCH -eq 0 ]
then
# Can't find information on package in apt cache
if [ $VERBOSE -eq 1 ]
then
echo "Unable to locate package $DEB_NAME version $DEB_VER" 1>&2
echo "in apt cache. It may have been installed directly, or the" 1>&2
echo "cache has been updated since installation and no longer" 1>&2
echo "contains information on that version. Omitting it in the" 1>&2
echo "list, since we can't determine where it came from." 1>&2
fi
echo "# Skipped $DEB_NAME $DEB_VER: not in apt cache"
elif [ "x$DEB_FILENAME" = "x" ]
then
# No filename, so package was installed via dpkg -i.
if [ $VERBOSE -eq 1 ]
then
echo "Package $DEB_NAME appears to have been installed directly" 1>&2
echo "(perhaps using 'dpkg -i'). Omitting it in the list, since we" 1>&2
echo "can't determine where it came from." 1>&2
fi
echo "# Skipped $DEB_NAME $DEB_VER: installed directly"
elif [ "x$DEB_FILENAME_IS_LOCAL" != "x" ]
then
# Package was installed from a local_packages directory.
# For example, chromeos-wm
if [ $VERBOSE -eq 1 ]
then
echo "Package $DEB_NAME appears to have been installed from a local" 1>&2
echo "package repository. Omitting it in the list, since future" 1>&2
echo "installs will also need to be local." 1>&2
fi
echo "# Skipped $DEB_NAME $DEB_VER $DEB_FILENAME: local install"
else
# Package from external repository.
# Don't change the order of these fields; make_local_repo.sh depends
# upon this order.
echo "$DEB_NAME $DEB_VER $DEB_PRIO $DEB_SECTION $DEB_FILENAME"
fi
}
# Header
echo "# Copyright (c) 2009 The Chromium Authors. All rights reserved."
echo "# Use of this source code is governed by a BSD-style license that can be"
echo "# found in the LICENSE file."
echo
echo "# Package list created by list_installed_packages.sh"
echo "# Creation time: `date`"
echo "#"
echo "# Contents of /etc/apt/sources.list:"
cat /etc/apt/sources.list | sed 's/^/# /'
echo "#"
echo "# package_name version priority section repo_filename"
# List all installed packages
for DEB in `dpkg-query --show -f='${Package}\n'`
do
print_deb $DEB
done