#! /bin/bash
#
# debuginfo can only be generated by rpm if it's used in its favourite
# environment (BUILD/, BUILDROOT/, etc...). Therefore --with-debuginfo
# is only available when generating source rpm package.
#
USAGE="[--format=rpm] [-j<n>] [--show-spec] [--spec=<specfile>] [--no-flavour] [source|headers|firmware]

   source            Package the kernel sources
   headers           Package the kernel header files
   firmware          Package the firmware

   --show-spec       Show the generated spec file and exit
   --spec            Specify the .spec file to use

   -j<n>             Used by make
"

rpm_variety=rpm

source $libexecdir/kdist-package--rpm-common


#
# We need a temporary directory for all cases.
#
cleanup_on_exit () {
	rm -fr $tmpdir
}
trap cleanup_on_exit 0

tmpdir=$(mktemp -d)

#
#
#
package_source () {
	git archive --format=tar HEAD | tar -C $tmpdir -xf -
	show_spec source >$rpm_name.spec &&
	rpmbuild --define "_builddir $tmpdir" --rmspec -bb $rpm_name.spec
}

package_firmware () {
	kdist__run_make -s INSTALL_MOD_PATH=$tmpdir firmware_install &&
	show_spec firmware >$rpm_name.spec &&
	rpmbuild --define "_builddir $tmpdir" --rmspec -bb $rpm_name.spec
}

package_headers () {
	kdist__run_make -s INSTALL_HDR_PATH=$tmpdir/usr headers_install &&
	show_spec headers >$rpm_name.spec &&
	rpmbuild --define "_builddir $tmpdir" --rmspec -bb $rpm_name.spec
}

cleanup_vmlinux () {
	rm -f develfiles.list
	rm -f $rpm_name.spec
	for f in $(ls $tmpdir); do
		mv $tmpdir/$f .
	done
}

package_vmlinux () {
	trap cleanup_vmlinux RETURN

	if test $with_flavour; then
		flavour=$(config__get_flavour .config)
		rpm_name=kernel${flavour:+-$flavour}
	fi
	uname_r=$KERNEL_RELEASE
	rpm_archive=$rpm_name-$uname_r

	#
	# Build number is always 0 for --format=rpm
	#
	rpm_release=${KERNEL_VERSION_PACKAGE:-0}.0${scmversion:++}

	case $(kdist__architecture) in
	x86_64)
		asmarch=x86
		rpm_exclusive=x86_64 ;;
	i386)
		asmarch=x86
		rpm_exclusive=%ix86 ;;
	esac

	have_modules=$(config__lookup_symbol MODULES .config)

	if test $spec_only; then
		show_spec vmlinux
		return
	fi

	kdist__run_make &&
	#
	# the spec file expects to find the devel files list in the
	# file 'develfiles.list'. Hopefully there's not such file in
	# the current directory, otherwise stash it temporarily.
	#
	if test $with_devel; then
		if test -f develfiles.list; then
			mv develfiles.list $tmpdir/
		fi &&
		package__list_devel_files >develfiles.list &&
		package__list_arch_devel_files $asmarch >develfiles-$asmarch.list
	fi &&
	#
	# Generate the ugliness and call the only tool that can parse
	# it. We still take care of a potential file with the same
	# name.
	#
	if test -f $rpm_name.spec; then
		mv $rpm_name.spec $tmpdir/
	fi &&
	show_spec vmlinux >$rpm_name.spec &&
	rpmbuild --nobuild $rpm_name.spec &&
	rpmbuild --define "_builddir $(pwd)" -bb $rpm_name.spec
}

#
# Main
#
targets=
varieties=
spec_only=
spec_file=
with_flavour=yes

shopt -s extglob

while
	case $1 in
	--show-spec)
		spec_only=yes ;;
	--spec=*)
		spec_file=${1#*=} ;;
	--with-devel)
		with_devel=yes ;;
	--no-flavour)
		unset with_flavour ;;
	-j*([[:digit:]]))
		KDIST_JOBS=$1 ;;
	-*)
		usage ;;
	*)
		break
	esac
do
	shift
done

if test $# -gt 1; then
	usage
fi

case $1 in
''|firmware|headers|source)
	target=$1 ;;
*)
	usage
esac


if [ -n "$spec_file" ]; then
	[ -r "$spec_file" ] ||
		die "failed to read '$spec_file'"
	# make the path absolute since we're going to move to the
	# kernel topdir.
	spec_file=$(readlink -f "$spec_file")
fi

#
# check the repo validity
#
kdist__cd_kernel_topdir || exit

#
# We just package tree, therefore user must commit his changes if he
# wants them included in the package.
#
git__check_clean_work_tree || exit

#
# We need the config file for kernel compilation and also to know if
# the kernel is using auto local version. If not don't use include it
# in the kernel names.
#
if ! test -f .config; then
	die "Kernel is not configured (missing .config file)."
fi

#
# Setup all version numbers...
#
kdist__setup_kernel_version &&
kdist__setup_kernel_release || exit

#
# version stuff: the flavour is moved to the begining of the rpm
# package name.
#
rpm_version=$KERNEL_VERSION_BASE

#
# This is also used by show_spec()
#
scmversion=$(git__scmversion)

#
# For firmware, source and headers targets uname_r is only the kernel
# release (no build number). But we always use the long scmversion for
# path installation, the short version being reserved for the package
# name.
#
uname_r=$KERNEL_VERSION$scmversion
rpm_archive=kernel-$uname_r

#
# rpm_log is used by show_spec: if there's no release information then
# we probably don't need to include the changelog.
#
rpm_log=false
if test $KERNEL_VERSION_PACKAGE; then
	rpm_log=true
fi

case $target in
firmware|headers|source)
	[ $with_devel ] && {
		die "Invalid --with-devel option with '$target'."
	}
	rpm_name=kernel-$target
	rpm_release=${KERNEL_VERSION_PACKAGE:-0}${scmversion:++}

	if test $spec_only; then
		show_spec $target
		return
	fi
	package_$target
	return
esac

package_vmlinux ||
die "Failed to build rpm package."

