#! /bin/bash

USAGE="--format=tar [-z|-j] [-o <path>] [-r <rev>] source|headers|devel

   source            Create a tarball of the kernel source
   headers           Create a tarball of the kernel headers
   devel             Create a tarball of the kernel devel files
   firmware          Create a tarball of all firmware

    -r               Specify the revision to archive
    -z               Create a tar.gz instead of a bare .tar
    -j               Create a tar.bz2 instead of a bare .tar
"

package_source () {
	git archive --format=tar --prefix=$prefix/ $rev
}

package_headers () {
	mkdir $tmpdir/source
	mkdir $tmpdir/$prefix

	#
	# If we're asking for a different revision then do the brut
	# force method...
	#
	if [ $rev != $HEAD ]; then
		git archive --format=tar $rev | {
			cd $tmpdir/source
			tar -xf -
		}
	fi &&
	make -s INSTALL_HDR_PATH=$tmpdir/$prefix headers_install &&
	tar -C $tmpdir -cf - $prefix
}

package_firmware () {
	mkdir $tmpdir/source
	mkdir $tmpdir/$prefix

	#
	# If we're asking for a different revision then do the brut
	# force method...
	#
	if [ $rev != $HEAD ]; then
		git archive --format=tar $rev | {
			cd $tmpdir/source
			tar -xf -
		}
	fi &&
	make -s INSTALL_MOD_PATH=$tmpdir/$prefix firmware_install &&
	tar -C $tmpdir -cf - $prefix
}

#
# This is the source devel package, it means that it misses the
# generated files and the .config. The main reason is that the
# generated files must be built on the system where this package will
# be installed.
#
package_devel () {
	files=$(package__list_devel_files --source-only --rev=$rev)
	files+=$(package__list_arch_devel_files --rev=$rev)

	#
	# Create an archive with the devel files only
	#
	git archive --format=tar --prefix=$prefix/ $rev $files

}

suffix=tar
zip=cat
output=
rev=

while
	case $1 in
	-z|--gzip)
		suffix=tar.gz
		zip=gzip ;;
	-j|--bzip2)
		suffix=tar.bz2
		zip=bzip2 ;;
	-o)
		shift
		output="$1" ;;
	-r)
		shift
		rev=$1 ;;
	-*)
		usage ;;
	*)
		break
	esac
do
	shift
done

case $#,$1 in
1,source|1,headers|1,devel|1,firmware) ;;
*) usage
esac

#
# Go to the kernel topdir so we can first adjust the tar filename:
# include the release version number.
#
kdist__cd_kernel_topdir || exit

git__check_clean_work_tree ||
	warn "You have local changes that won't be included in the tarball"

#
# Setup the revision
#
if ! test $rev; then
	rev=$(git describe --tags --abbrev=4 HEAD)
fi

#
# figure out the filename of the archive
#
prefix=kernel-$1-${rev#v}

#
# resolve the revision so we can compare it later with the current
# HEAD.
#
rev=$(git rev-parse --verify $rev^{commit}) &&
HEAD=$(git rev-parse --verify HEAD) ||
exit

tar=/dev/stdout
if test -n "$output"; then
	tar=$output
	if test -d "$output"; then
		tar+=/$prefix.$suffix
		output=
	fi
else
	if test -t 1; then
		tar=$prefix.$suffix
	fi
fi


#
# Do the tarball
#
cleanup_on_exit () {
	if [ $tar ] && [ $tar != /dev/stdout ]; then
		rm -f $tar
	fi
	rm -fr $tmpdir
}

trap cleanup_on_exit 0

tmpdir=$(mktemp -d)

#
# generate the package
#
set -o pipefail

{ package_$1 | $zip; }>$tar || {
	die "Failed to generate the archive."
}

if ! [ $output ]; then
	echo $tar
fi
tar=
