Last active
May 27, 2021 14:32
-
-
Save Hayao0819/d0df4d19b155b28fdfb14bc38b4ed8cb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -eu | |
script_path="$( cd -P "$( dirname "$(readlink -f "${0}")" )" && pwd )" | |
pacman_dbpath="$(pacman-conf "DBPath")" | |
debug=false | |
work_dir="/tmp/expac" | |
expac_version="0.1" | |
msg_error(){ echo "[expac] Error ${*}" 1>&2; } | |
msg_info (){ echo "[expac] Info ${*}" 1>&2; } | |
msg_warn (){ echo "[expac] Warn ${*}" 1>&2; } | |
msg_debug(){ [[ "${debug}" = true ]] && echo "[expac] Debug ${*}" 1>&2; return 0;} | |
_help() { | |
echo "usage ${0} [options] [package]" | |
echo | |
echo " General options:" | |
echo " -h | --help This help message" | |
echo | |
echo " --debug Enable debug mode" | |
echo " --dbpath Set datebase dir" | |
} | |
# readdb <file> <section> | |
readdb(){ | |
local _path="${1}" _section="${2}" _dblines _line _in_section=false | |
readarray -t _dblines < "${_path}" | |
for _line in "${_dblines[@]}"; do | |
case "${_line}" in | |
"%${_section}%") | |
_in_section=true | |
continue | |
;; | |
"%"*"%") | |
_in_section=false | |
continue | |
;; | |
esac | |
[[ "${_in_section}" = true ]] && [[ -n "${_line}" ]] && echo "${_line}" | |
done | |
} | |
# exportpkg <package>cat | |
exportpkg(){ | |
local _version _package="${1}" _datebase _filelist=() | |
# Check package | |
if ! pacman -Qq "${_package}" 1> /dev/null 2>&1; then | |
msg_error "${_package} is not installed" | |
exit 1 | |
fi | |
# Set package info | |
_package="$(pacman -Q "${_package}" 2> /dev/null | cut -d " " -f 1)" | |
_version="$(pacman -Q "${_package}" 2> /dev/null | cut -d " " -f 2)" | |
_datebase="${pacman_dbpath}/local/${_package}-${_version}" | |
msg_debug "Package datebase is ${_datebase}" | |
# Read datebase | |
msg_info "Loading package datebase ..." | |
readarray -t _db_filelist < <(readdb "${_datebase}/files" FILES | grep -v "/$") | |
readarray -t _db_depends < <(readdb "${_datebase}/desc" "DEPENDS") | |
for _data in "NAME" "VERSION" "BASE" "DESC" "URL" "ARCH" "BUILDDATE" "INSTALLDATE" "PACKAGER" "SIZE" "LICENSE" "VALIDATION"; do | |
#readarray -t "_db_${_data,,}" < <(readdb "${_datebase}/desc" "${_data}") | |
printf -v "_db_${_data,,}" "$(readdb "${_datebase}/desc" "${_data}")" | |
done | |
# Create BUILDINFO | |
msg_info "Creating .BUILDINFO ..." | |
mkdir -p "${work_dir}/${_package}" | |
local _buildinfo="${work_dir}/${_package}/.BUILDINFO" _write_buildinfo | |
function _write_buildinfo(){ echo "${1} = ${2}" >> "${_buildinfo}"; } | |
echo -n > "${_buildinfo}" | |
_write_buildinfo "format" "1" | |
_write_buildinfo "pkgname" "${_package}" | |
_write_buildinfo "pkgbase" "${_db_base}" | |
_write_buildinfo "pkgver" "${_db_version}" | |
_write_buildinfo "pkgarch" "${_db_arch}" | |
_write_buildinfo "packager" "${_db_packager}" | |
_write_buildinfo "builddate" "${_db_builddate}" | |
_write_buildinfo "builddir" "${work_dir}/${_package}" | |
while read -r _pkg; do | |
_write_buildinfo "installed" "${_pkg}-$(readdb "${pacman_dbpath}/local/${_pkg}/desc" "ARCH")" | |
done < <(pacman -Q --color never | tr " " "-") | |
# Create PKGINFO | |
msg_info "Creating .PKGINFO ..." | |
local _write_pkginfo _pkginfo="${work_dir}/${_package}/.PKGINFO" | |
function _write_pkginfo(){ echo "${1} = ${2}" >> "${_pkginfo}"; } | |
echo "# Generated by expac ${expac_version}" > "${_pkginfo}" | |
_write_pkginfo "pkgname" "${_package}" | |
_write_pkginfo "pkgbase" "${_db_base}" | |
_write_pkginfo "pkgver" "${_db_version}" | |
_write_pkginfo "pkgdesc" "${_db_desc}" | |
_write_pkginfo "url" "${_db_url}" | |
_write_pkginfo "builddate" "${_db_builddate}" | |
_write_pkginfo "packager" "${_db_packager}" | |
_write_pkginfo "size" "${_db_size}" | |
_write_pkginfo "arch" "${_db_arch}" | |
_write_pkginfo "license" "${_db_license}" | |
for _pkg in "${_db_depends[@]}"; do | |
_write_pkginfo "depend" "${_pkg}" | |
done | |
# Create MTREE | |
msg_info "Creating .MTRE ..." | |
cp -a "${_datebase}/mtree" "${work_dir}/${_package}/.MTREE" | |
# Copy files | |
for _file in "${_db_filelist[@]}"; do | |
if [[ -f "/${_file}" ]]; then | |
msg_info "Copying ${_file}" | |
mkdir -p "${work_dir}/${_package}/$(dirname "${_file}")" | |
cp -a "/${_file}" "${work_dir}/${_package}/$(dirname "${_file}")" | |
else | |
msg_warn "${_file} was not found" | |
fi | |
done | |
# Create archive | |
( | |
cd "${work_dir}/${_package}" | |
readarray -t _archive_list < <(find ./ -mindepth 1 -maxdepth 1 -printf "%P\n") | |
tar -v -c -I zstd -f "${script_path}/${_package}-${_db_version}-${_db_arch}.pkg.tar.zst" "${_archive_list[@]}" | |
) | |
} | |
# Parse options | |
OPTS=("h") | |
OPTL=("debug" "help" "dbpath:") | |
if ! OPT=$(getopt -o "$(printf "%s," "${OPTS[@]}")" -l "$(printf "%s," "${OPTL[@]}")" -- "${@}"); then | |
exit 1 | |
fi | |
eval set -- "${OPT}" | |
msg_debug "Argument: ${OPT}" | |
unset OPT OPTS OPTL | |
while true; do | |
case "${1}" in | |
--debug) | |
debug=true | |
shift 1 | |
;; | |
--dbpath) | |
pacman_dbpath="${2}" | |
shift 2 | |
;; | |
-h | --help) | |
_help | |
exit 0 | |
;; | |
--) | |
shift | |
break | |
;; | |
*) | |
msg_error "Invalid argument '${1}'" | |
_help | |
exit 1 | |
;; | |
esac | |
done | |
for pkg in "${@}"; do | |
exportpkg "${pkg}" | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment