Artifact Content

Artifact 7f99548475fce315d8a8ce5c173ba6d4cb33bbbe:


#! /usr/bin/env bash

if [ "$1" == '--cpio' ]; then
	mode='file'

	pkgfile="$1"
else
	mode='dir'

	pkgsdir="$1"
fi
appfsdir="$2"

if [ -z "${pkgsdir}" -a -z "${pkgfile}" ] || [ -z "${appfsdir}" ]; then
	echo 'Usage: appfs-mk {--cpio <pkgfile>|<pkgsdir>} <appfsdir>' >&2

	exit 1
fi

appfsdir="$(cd "${appfsdir}" && pwd)"
if [ -z "${appfsdir}" ]; then
	echo "Unable to find appfs directory." >&2

	exit 1
fi

mkdir -p "${appfsdir}/sha1"

function sha1() {
	local filename

	filename="$1"

	openssl sha1 "${filename}" | sed 's@.*= @@'
}

function emit_manifest() {
	find . -print0 | while IFS='' read -r -d $'\0' filename; do
		if [ "${filename}" = '.' ]; then
			continue
		fi

		filename="$(echo "${filename}" | sed 's@^\./@@' | head -n 1)"

		if [ ! -e "${filename}" ]; then
			continue
		fi

		if [ -h "${filename}" ]; then
			type='symlink'
		elif [ -d "${filename}" ]; then
			type='directory'
		elif [ -f "${filename}" ]; then
			type='file'
		else
			continue
		fi

		case "${type}" in
			directory)
				stat_format='%Y'
				extra_data=''
				;;
			symlink)
				stat_format='%Y'
				extra_data="$(readlink "${filename}")"
				;;
			file)
				if [ -x "${filename}" ]; then
					extra_data='x'
				else
					extra_data=''
				fi

				stat_format='%Y,%s'
				filename_hash="$(sha1 "${filename}")"
				extra_data="${extra_data},${filename_hash}"

				filename_intree="${appfsdir}/sha1/${filename_hash}"

				if [ ! -e "${filename_intree}" ]; then
					cat "${filename}" > "${filename_intree}.tmp"

					mv "${filename_intree}.tmp" "${filename_intree}"
				fi
				;;
		esac
		stat_data="$(stat --format="${stat_format}" "${filename}")"

		if [ -z "${extra_data}" ]; then
			echo "${type},${stat_data},${filename}"
		else
			echo "${type},${stat_data},${extra_data},${filename}"
		fi
	done
}

case "${mode}" in
	dir)
		cd "${pkgsdir}" || exit 1
		;;
	file)
		echo 'Unsupported' >&2
		exit 1
		;;
esac

packagelistfile="${appfsdir}/sha1/${RANDOM}${RANDOM}${RANDOM}${RANDOM}${RANDOM}.tmp"
for package in *; do
	(
		cd "${package}" || exit 1

		for os_cpuArch in *; do
			os="$(echo "${os_cpuArch}" | cut -f 1 -d '-')"
			cpuArch="$(echo "${os_cpuArch}" | cut -f 2- -d '-')"

			(
				cd "${os_cpuArch}" || exit 1

				for version in *; do
					if [ -h "${version}" ]; then
						continue
					fi

					manifestfile="${appfsdir}/sha1/${RANDOM}${RANDOM}${RANDOM}${RANDOM}${RANDOM}.tmp"

					(
						cd "${version}" || exit 1

						echo "#manifestmetadata,${package},${os},${cpuArch},${version}"
						emit_manifest
					) > "${manifestfile}"

					manifestfile_hash="$(sha1 "${manifestfile}")"
					mv "${manifestfile}" "${appfsdir}/sha1/${manifestfile_hash}"

					# XXX:TODO: Determine if this is the latest version
					isLatest='0'

					echo "${package},${version},${os},${cpuArch},${manifestfile_hash},${isLatest}"
				done

			)
		done
	)

done > "${packagelistfile}"
packagelistfile_hash="$(sha1 "${packagelistfile}")"
mv "${packagelistfile}" "${appfsdir}/sha1/${packagelistfile_hash}"

echo "${packagelistfile_hash},sha1" > "${appfsdir}/index"