File:  [cvs.NetBSD.org] / pkgsrc / pkgtools / pkg_tarup / files / pkg_tarup
Revision 1.24: download - view: text, annotated - select for diffs
Sat Mar 19 09:44:17 2011 UTC (14 years, 1 month ago) by wiz
Branches: MAIN
CVS tags: pkgsrc-2011Q3-base, pkgsrc-2011Q3, pkgsrc-2011Q2-base, pkgsrc-2011Q2, pkgsrc-2011Q1-base, pkgsrc-2011Q1, HEAD
Add filebase support, allowing to choose the filename for the resulting
package; from Aleksey Cheusov in relation to PR 44698.

Bump version to 1.9.

#! @SH@
#
# $Id: pkg_tarup,v 1.24 2011/03/19 09:44:17 wiz Exp $
#
# Tar up installed package
#
# Package names are assumed to not contain spaces.
#
# (c) Copyright 2000-2002 Hubert Feyrer <hubert@feyrer.de>
#

PREFIX=${PREFIX:-@PREFIX@}

PATH=${PREFIX}/sbin:${PREFIX}/bin:/sbin:/bin:/usr/sbin:/usr/bin:@PKG_TOOLS_BIN@
export PATH

OS=`uname -s`

ECHO=${ECHO:-@ECHO@}
ECHO_N=${ECHO_N:-@ECHO_N@}
HEAD=${HEAD:-@HEAD@}
ID=${ID:-@ID@}
ROOT_USER=${ROOT_USER:-@ROOT_USER@}
SED=${SED:-@SED@}
SU_CMD=${SU_CMD:-@SU_CMD@}
GREP=${GREP:-@GREP@}
XARGS=${XARGS:-@XARGS@}

root_uid=`${ID} -u ${ROOT_USER} 2>/dev/null`
if [ "$root_uid" = "" ]; then
	echo "$0: root user \"${ROOT_USER}\" does not exist." 1>&2
	exit 1
fi

if [ `${ID} -u` != "$root_uid" ]; then
	${ECHO} "Becoming ${ROOT_USER}@`/bin/hostname` to create a binary package"
	${ECHO_N} "`${ECHO} ${SU_CMD} | ${SED} -e's/[[:space:]].*//'` ";\
	( for arg in "$@"; do echo \"${arg}\"; done ) |
	${SU_CMD} "exec ${XARGS} \"$0\""
	exit $?
fi

PKG_DBDIR=${PKG_DBDIR:-@PKG_DBDIR@}
PKG_SUFX=${PKG_SUFX:-@PKG_SUFX@}

PKGREPOSITORY=${PKGREPOSITORY:-/tmp}

# XXX Force pkg_info to ignore .tgz files.
export PKG_PATH=

# Set to 1 if we also want to tar up dependencies also
GETDEPS=0

usage()
{
	cat <<'EOF'
Usage: pkg_tarup [OPTIONS] installed_pkg|pattern [...]
OPTIONS:
   -a                 - Create packages for all dependent packages too.
   -d <pkgrepository> - Set the destination directory for packages.
   -f <filebase>      - Set the filebase.
   -K <pkg_dbdir>     - Set the package database directory.
   -s <pkg_sufx>      - Set the extension used for the created package(s).
The following environment variables are used:
 (unless overriden by command line parameters)
 PKGREPOSITORY - A destination directory for packages (/tmp)
 PKG_DBDIR     - The location of the package database directory
 PKG_SUFX      - The suffix to append to the package (.tgz)
EOF
	exit 1
}

check_and_add()
{
	opt="$1"
	file="$2"

	if [ x"$opt" = x"" -o x"$file" = x"" ]; then
	   ${ECHO} Usage: check_and_add -opt +FILE
	   exit 1
	fi

	if [ -f "$file" ]
	then
	    PKG_ARGS="${PKG_ARGS} \"${opt}\" \"${file}\""
	fi
}

create_package()
{
	PKG="$1"
	if [ -n "$FILEBASE" ]; then
	    PKGFILE=`echo "$PKG" | sed 's/^\(.*\)\(-[0-9][^-]*$\)/'"$FILEBASE"'\2/'`
	else
	    PKGFILE="$PKG"
	fi
	PKG_ARGS=
	${ECHO} "Creating binary package: $PKGFILE"

	check_and_add -c "${PKG_DBDIR}/${PKG}/+COMMENT"
	check_and_add -d "${PKG_DBDIR}/${PKG}/+DESC"
	check_and_add -b "${PKG_DBDIR}/${PKG}/+BUILD_VERSION"
	check_and_add -B "${PKG_DBDIR}/${PKG}/+BUILD_INFO"
	check_and_add -s "${PKG_DBDIR}/${PKG}/+SIZE_PKG"
	check_and_add -S "${PKG_DBDIR}/${PKG}/+SIZE_ALL"
	check_and_add -i "${PKG_DBDIR}/${PKG}/+INSTALL"
	check_and_add -k "${PKG_DBDIR}/${PKG}/+DEINSTALL"
	check_and_add -D "${PKG_DBDIR}/${PKG}/+DISPLAY"
	check_and_add -m "${PKG_DBDIR}/${PKG}/+MTREE"
	check_and_add -n "${PKG_DBDIR}/${PKG}/+PRESERVE"

	PLIST=/tmp/+CONTENTS.$$

	# This sed command trims out all of the following:
	# md5 magic comments, symlink magic comments
	# lines starting with @blddep, @pkgdep, @pkgcfl, @name, @mtree
	# @cwd lines that refer to the current directory "@cwd ."
	# @ignore and any line immediately following it
	${SED} \
		-e '/^@comment MD5:/d' \
		-e '/^@comment Symlink:/d' \
		-e '/^@mtree/d' \
		-e '/^@cwd/d' \
		-e '/^@src/d' \
		-e '/^@ignore/,/^.*$/d' \
		<"${PKG_DBDIR}/${PKG}/+CONTENTS" >"${PLIST}"

	# ${ECHO} -----
	# cat $PLIST
	# ${ECHO} -----
	# exit 0

	# Just for kicks ...
	# pkg_admin check "${PKG}"

	# It's kind of silly to jump through hoops to get stuff with spaces
	# here, since we have no way to pass it to pkg_create, but maybe someone
	# will care enough to fix the rest of this.
	PKG_PREFIX=`pkg_info -qp "${PKG}" | ${HEAD} -1 | ${SED} -e's/^@cwd[[:space:]]*//'`

	PKG_ARGS="${PKG_ARGS} -v"
	PKG_ARGS="${PKG_ARGS} -f \"${PLIST}\""
	PKG_ARGS="${PKG_ARGS} -l"
	PKG_ARGS="${PKG_ARGS} -p \"${PKG_PREFIX}\""
	PKG_ARGS="${PKG_ARGS} -I \"${PKG_PREFIX}\""
	PKG_ARGS="${PKG_ARGS} \"${PKGREPOSITORY}/${PKGFILE}${PKG_SUFX}\""
	if [ -f "${PKG_DBDIR}/${PKG}/+VIEWS" ]
	then
		PKG_ARGS="${PKG_ARGS} -E"
	fi
	eval pkg_create "${PKG_ARGS}"

	rm -f "${PLIST}"
	return 0
}

add_to_list()
{
	local added

	added=0

	oIFS="$IFS"
	IFS="
"
	# Get expanded name, and escape quotes
	for rPKG in `pkg_info -e "$1" | ${SED} -e's/\"/\\\"/g'` ; do
		if [ -z "$rPKG" -o -f "${PKG_DBDIR}/${rPKG}" ] ; then
			${ECHO} "Error: package $1 not found"
			usage
		fi

		added=1
		if ! ${ECHO} "${PKGS}" | ${GREP} -q "\"${rPKG}\"" ; then
			PKGS="${PKGS} \"${rPKG}\""
		fi
	done
	IFS="$oIFS"
	if [ $added -eq 0 ] ; then
		${ECHO} "Warning: no package matching $1 found"
	fi
}


while [ $# -gt 0 ] ; do
	case "$1" in
	-a)
		GETDEPS=1
		shift
		;;
	-d)
		PKGREPOSITORY="$2"
		shift 2
		;;
	-h)
		usage
		exit 0
		;;
	-K)
		PKG_DBDIR="$2"
		shift 2
		;;
	-s)
		PKG_SUFX="$2"
		shift 2
		;;
	-f)
		FILEBASE="$2"
		shift 2
		;;
	*)
		break
		;;
	esac
done

add_all_deps_to_list()
{
	# Make the input separator only a newline so spaces are allowed
	oIFS="$IFS"
	IFS="
"
	for f in `pkg_info -qf "$1" | ${GREP} @pkgdep | ${SED} -e's/^@pkgdep[[:space:]]*//' ` ; do
		add_to_list "$f"
		add_all_deps_to_list "$f"
	done
	IFS="$oIFS"
}

arg_cnt ()
{
	echo $#
}

while [ $# -gt 0 ] ; do
	add_to_list "$1"
	if [ $GETDEPS -eq 1 ] ; then
		add_all_deps_to_list "$1"
	fi
	shift
done
if [ -n "$FILEBASE" ]; then
	if [ `arg_cnt ${PKGS}` -ne 1 ] ; then
		${ECHO} "ERROR: -f cannot be used for creating multiple packages!"
		exit 1
	fi
fi
if [ -z "${PKGS}" ] ; then
	${ECHO} "ERROR: No packages to tarup identified!"
	usage
fi
FOR="
for xPKG in ${PKGS} ; do
	create_package \"\${xPKG}\"
	if [ \$? -ne 0 ] ; then 
		exit 1
	fi
done"
eval "${FOR}"

exit 0


+REQUIRED_BY:

 - maybe the squirelling away of +REQUIRED_BY should be done here
   instead of in the bsd.pkg.mk framework that normally calls this.


mtree file considerations:

 - keeping uncompressed mtree file adds ~10% to the size of /var/db/pkg

 - could gzip file, space saving: 5kb->850b (plus some intelligence to
   uncompress them when needed)

 - not keeping mtree file results in pkgs w/o mtree file (but should work)

integration:

 - how/where?  I'd prefer not to have yet another pkg_* utility flying
   around, integration into pkg_admin would be nice.  But how merge a
   shell script into a C executable?  REWRITE in C of course!  ;-)

CVSweb <webmaster@jp.NetBSD.org>