563 lines
16 KiB
Bash
Executable File
563 lines
16 KiB
Bash
Executable File
#!/bin/bash
|
|
set -e
|
|
|
|
RED_COLOR="\e[1;31m"
|
|
PURPLE_COLOR="\e[1;35m"
|
|
GREEN_COLOR="\e[1;32m"
|
|
CLEAR_COLOR="\e[0m"
|
|
|
|
_DEF_PARALLEL_JOBS=4
|
|
_ENV_PARALLEL_JOBS="${PARALLEL_JOBS}"
|
|
source /etc/leaf.conf
|
|
if [ -n "${_ENV_PARALLEL_JOBS}" ]; then
|
|
export PARALLEL_JOBS="${_ENV_PARALLEL_JOBS}"
|
|
elif [ -z "${PARALLEL_JOBS}" ]; then
|
|
export PARALLEL_JOBS="${_DEF_PARALLEL_JOBS}"
|
|
else
|
|
export PARALLEL_JOBS
|
|
fi
|
|
export MAKEFLAGS="-j${PARALLEL_JOBS}"
|
|
export NINJAJOBS="${PARALLEL_JOBS}"
|
|
export LC_ALL=C
|
|
export leaf_flags="CFLAGS CXXFLAGS FCFLAGS FFLAGS RUSTFLAGS"
|
|
for flag in ${leaf_flags}; do
|
|
export $flag
|
|
done
|
|
|
|
declare -A BUILD_OPTIONS
|
|
BUILD_OPTIONS=([strip]="0" [libtool]="0" [zipman]="0")
|
|
|
|
main() {
|
|
leaf_check_directories
|
|
if [ $# -le 1 ]; then
|
|
case $1 in
|
|
clean)
|
|
leaf_check_permission
|
|
rm -rf {"${BUILD_DIR}","${TEMP_DIR}"}/*
|
|
;;
|
|
list)
|
|
cat "${INSTALLED_PACKAGES}"
|
|
;;
|
|
*)
|
|
leaf_print_usage
|
|
;;
|
|
esac
|
|
else
|
|
local _item
|
|
case $1 in
|
|
prepare|build|install|force-install|remove|pack|dirct-install)
|
|
leaf_check_permission
|
|
for _item in "${@:2}"; do
|
|
leaf_find_pkgbuild "${_item}"
|
|
leaf_reset_state
|
|
source "${PKGBUILD_DIR}/${PKG_PREFIX}/${PKG_NAME}".PKGBUILD
|
|
leaf_parse_options
|
|
srcdir="${BUILD_DIR}/${PKG_PREFIX}/${PKG_NAME}"
|
|
pkgdir="${srcdir}"/__pkgdir__
|
|
if [[ x"$1" != x"dirct-install" ]]; then
|
|
rm -rf "${srcdir}" && install -dm755 "${srcdir}" && cd "${srcdir}"
|
|
fi
|
|
leaf_${1}_package
|
|
done
|
|
;;
|
|
search)
|
|
leaf_search_package "${@:2}"
|
|
;;
|
|
show)
|
|
for _item in "${@:2}"; do
|
|
leaf_find_pkgbuild "${_item}"
|
|
leaf_show_package
|
|
done
|
|
;;
|
|
unpack)
|
|
for _item in "${@:2}"; do
|
|
leaf_check_permission
|
|
leaf_reset_state
|
|
leaf_unpack_package "${_item}"
|
|
done
|
|
;;
|
|
*)
|
|
leaf_print_usage
|
|
;;
|
|
esac
|
|
if [ -n "${MESSAGE}" ]; then
|
|
echo -e "${MESSAGE}"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
###########################################################
|
|
# Help functions that give PKGBUILD to use
|
|
###########################################################
|
|
|
|
leaf_clear_flags() {
|
|
for flag in $leaf_flags; do
|
|
unset $flag
|
|
done
|
|
}
|
|
|
|
leaf_install_hook() {
|
|
local _hook_file="$1"
|
|
local _hook_dest="${pkgdir}${HOOK_DIR}"
|
|
|
|
# check file name
|
|
[[ -f "$_hook_file" ]] || leaf_error "Hook file '$_hook_file' does not exist"
|
|
[[ -r "$_hook_file" ]] || leaf_error "Hook file '$_hook_file' is not readable"
|
|
[[ "$(basename "$_hook_file")" == *.HOOK ]] || leaf_error "Hook file must end with .HOOK extension"
|
|
|
|
# check hook file by load it in a sub shell
|
|
(
|
|
unset triggers target operation 2>/dev/null
|
|
declare -a triggers
|
|
declare -a target
|
|
source "$_hook_file" || leaf_error "Source ${_hook_file} failed."
|
|
[[ ${#triggers[@]} -gt 0 ]] || leaf_error "${_hook_file} missing 'triggers' array"
|
|
[[ ${#target[@]} -gt 0 ]] || leaf_error "${_hook_file} missing 'target' array"
|
|
declare -f operation &>/dev/null || leaf_error "${_hook_file} missing 'operation' function"
|
|
) || leaf_error "Hook file ${_hook_file} is not valid. Please check your package ${PKG_NAME}."
|
|
|
|
# install hook file
|
|
install -Dm644 -- "$_hook_file" "${_hook_dest}/$(basename "$_hook_file")" || {
|
|
leaf_error "Failed to install hook file to ${_hook_dest}"
|
|
}
|
|
|
|
echo -e "Installed hook: $(basename "$_hook_file")"
|
|
}
|
|
|
|
leaf_check_directories() {
|
|
if [ -z "${BUILD_DIR}" ]; then
|
|
leaf_error "Directory \${BUILD_DIR} must be existed"
|
|
elif [ -z "${TEMP_DIR}" ]; then
|
|
leaf_error "Directory \${TEMP_DIR} must be existed"
|
|
fi
|
|
}
|
|
|
|
leaf_check_permission() {
|
|
[ ${EUID} -eq 0 ] || leaf_error "Permission denied"
|
|
}
|
|
|
|
leaf_compress_man_pages() {
|
|
pushd "${pkgdir}" > /dev/null 2>&1
|
|
[ ! -d usr/share/man ] || {
|
|
local _item
|
|
find usr/share/man -type f,l | while read -r _item; do
|
|
case $(file -bi "${_item}") in
|
|
*text*)
|
|
/usr/bin/gzip -c -9 "${_item}" > "${_item}".gz
|
|
rm -fv "${_item}"
|
|
;;
|
|
*symlink*)
|
|
ln -srv "$(readlink -m "${_item}")".gz "$(realpath "${_item}".gz)"
|
|
rm -fv "${_item}"
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
popd > /dev/null 2>&1
|
|
}
|
|
|
|
leaf_error() {
|
|
if [ -n "${MESSAGE}" ]; then
|
|
echo -e "${MESSAGE}"
|
|
fi
|
|
echo -e "${RED_COLOR}* $1${CLEAR_COLOR}" && exit 1
|
|
}
|
|
|
|
leaf_find_pkgbuild() {
|
|
local _location="$(find "${PKGBUILD_DIR}" -type f -wholename "*$1*.PKGBUILD" -printf "%P\n")"
|
|
if [ -z "${_location}" ]; then
|
|
leaf_error "Package $1's PKGBUILD does NOT exist"
|
|
elif [[ $(echo "${_location}" | wc -l) == 1 ]]; then
|
|
PKG_PREFIX="$(echo "${_location}" | awk -F'/' '{print $1}')"
|
|
PKG_NAME="$(echo "${_location%.PKGBUILD}" | awk -F'/' '{print $2}')"
|
|
else
|
|
leaf_error "Ambiguous packages, the prefix or version of package must be specified"
|
|
fi
|
|
}
|
|
|
|
leaf_invoke_hooks() {
|
|
local _hook _target _hook_dir
|
|
local _trace_dir="${TRACE_DIR}/${PKG_PREFIX}/${PKG_NAME}"
|
|
case "$1" in
|
|
install|remove)
|
|
;;
|
|
*)
|
|
leaf_error "leaf_invoke_hooks: $1 is invalid!"
|
|
;;
|
|
esac
|
|
if [ ! -d "${HOOK_DIR}" ]; then
|
|
leaf_error "Hook dir ${HOOK_DIR} does not exist. Check your leaf installation."
|
|
fi
|
|
find "${HOOK_DIR}" -type f -name "*.HOOK" | while read -r _hook; do
|
|
unset triggers target operation
|
|
declare -a triggers
|
|
declare -a target
|
|
source "${_hook}" || leaf_error "Failed to source hook file: ${_hook}"
|
|
[[ " ${triggers[*]} " =~ " $1 " ]] || continue
|
|
for _target in "${target[@]}"; do
|
|
if grep -qe "${_target}" "${_trace_dir}"/FILES 2>/dev/null; then
|
|
operation
|
|
break
|
|
fi
|
|
done
|
|
done
|
|
}
|
|
|
|
leaf_merge_package() {
|
|
pushd $1 > /dev/null 2>&1
|
|
local _trace_dir="${TRACE_DIR}/${PKG_PREFIX}/${PKG_NAME}"
|
|
local _item _item_conflict _mode _owner _group
|
|
local _time="$(date +%Y%m%d%H%M%S)"
|
|
cat "${_trace_dir}"/DIRS | while read -r _item; do
|
|
_mode=$(stat -c %a ."${_item}")
|
|
_owner=$(stat -c %u ."${_item}")
|
|
_group=$(stat -c %g ."${_item}")
|
|
install -d -m ${_mode} -o ${_owner} -g ${_group} "${_item}"
|
|
done
|
|
cat "${_trace_dir}"/FILES | while read -r _item; do
|
|
_mode=$(stat -c %a ."${_item}")
|
|
_owner=$(stat -c %u ."${_item}")
|
|
_group=$(stat -c %g ."${_item}")
|
|
if [[ "${_item}" == /etc/* && -e "${_item}" ]]; then
|
|
_item_conflict="$(dirname "${_item}")/._$(basename "${_item}").conflict_${PKG_NAME}_${_time}"
|
|
install -D -m ${_mode} -o ${_owner} -g ${_group} ."${_item}" "${_item_conflict}"
|
|
leaf_record_message "Config file confliction on ${_item}, the package provided version is installed as ${_item_conflict}."
|
|
else
|
|
install -D -m ${_mode} -o ${_owner} -g ${_group} ."${_item}" "${_item}"
|
|
fi
|
|
done
|
|
cat "${_trace_dir}"/LINKS | while read -r _item; do
|
|
cp -dp ."${_item}" "${_item}"
|
|
done
|
|
leaf_invoke_hooks install
|
|
popd > /dev/null 2>&1
|
|
}
|
|
|
|
leaf_parse_options() {
|
|
local _option_array=(${DEFAULT_BUILD_OPTIONS[@]} ${options[@]})
|
|
for option in ${_option_array[@]}; do
|
|
if [[ x"${option}" == x"strip" ]]; then
|
|
BUILD_OPTIONS["strip"]="1"
|
|
fi
|
|
if [[ x"${option}" == x"!strip" ]]; then
|
|
BUILD_OPTIONS["strip"]="0"
|
|
fi
|
|
if [[ x"${option}" == x"libtool" ]]; then
|
|
BUILD_OPTIONS["libtool"]="1"
|
|
fi
|
|
if [[ x"${option}" == x"!libtool" ]]; then
|
|
BUILD_OPTIONS["libtool"]="0"
|
|
fi
|
|
if [[ x"${option}" == x"zipman" ]]; then
|
|
BUILD_OPTIONS["zipman"]="1"
|
|
fi
|
|
if [[ x"${option}" == x"!zipman" ]]; then
|
|
BUILD_OPTIONS["zipman"]="0"
|
|
fi
|
|
done
|
|
}
|
|
|
|
leaf_print_usage() {
|
|
cat << EOF
|
|
Usage: leaf [option] [packages]
|
|
Option: prepare prepare packages but do not build
|
|
build build packages but do not install
|
|
install install packages
|
|
forece-install install packages even if test faild
|
|
dirct-install install packages directly from previous build
|
|
remove remove packages
|
|
clean clean all source folders
|
|
list list installed packages
|
|
search search packages by keyword
|
|
show show package details
|
|
pack build packages and pack
|
|
unpack unpack binary packages
|
|
This leaf does not have Super Cow Powers.
|
|
EOF
|
|
}
|
|
|
|
leaf_record_message() {
|
|
MESSAGE+="\n${PURPLE_COLOR}* Message from ${PKG_PREFIX}/${PKG_NAME}${CLEAR_COLOR}\n"
|
|
local _item
|
|
for _item in "${@:1}"; do
|
|
MESSAGE+="${GREEN_COLOR}* ${_item}${CLEAR_COLOR}\n"
|
|
done
|
|
}
|
|
|
|
leaf_remove_libtool_files() {
|
|
find "${pkgdir}" -name "*.la" -delete
|
|
}
|
|
|
|
leaf_reset_state() {
|
|
options=()
|
|
src_preinstall() {
|
|
:
|
|
}
|
|
src_postinstall() {
|
|
:
|
|
}
|
|
src_preremove() {
|
|
:
|
|
}
|
|
src_postremove() {
|
|
:
|
|
}
|
|
src_prepare() {
|
|
:
|
|
}
|
|
src_build() {
|
|
:
|
|
}
|
|
src_check() {
|
|
:
|
|
}
|
|
}
|
|
|
|
leaf_strip_files() {
|
|
pushd "${pkgdir}" > /dev/null 2>&1
|
|
local _file
|
|
find . -type f | while read -r _file; do
|
|
case $(file -bi "${_file}") in
|
|
*application/x-sharedlib*) # libraries(.so)
|
|
strip --strip-unneeded "${_file}"
|
|
;;
|
|
*application/x-pie-executable*) # libraries(.so)
|
|
strip --strip-unneeded "${_file}"
|
|
;;
|
|
*application/x-archive*) # libraries(.a)
|
|
strip --strip-debug "${_file}"
|
|
;;
|
|
*application/x-object*)
|
|
case "${_file}" in
|
|
*.ko) # kernel module
|
|
strip --strip-unneeded "${_file}"
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
;;
|
|
*application/x-executable*) # binaries
|
|
strip --strip-all "${_file}"
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
done
|
|
popd > /dev/null 2>&1
|
|
}
|
|
|
|
leaf_trace_package() {
|
|
pushd "$1" > /dev/null 2>&1
|
|
local _trace_dir="${TRACE_DIR}/${PKG_PREFIX}/${PKG_NAME}"
|
|
install -dm755 "${_trace_dir}"
|
|
find . -type d | sort > "${_trace_dir}"/DIRS
|
|
sed -i "1d" "$_trace_dir"/DIRS
|
|
find . -type f | sort > "${_trace_dir}"/FILES
|
|
find . -type l | sort > "${_trace_dir}"/LINKS
|
|
sed -i "s/.//" "${_trace_dir}"/{DIRS,FILES,LINKS}
|
|
popd > /dev/null 2>&1
|
|
}
|
|
|
|
leaf_update_package_database() {
|
|
local _item="$(echo "$2" | awk 'BEGIN{FS="/";OFS="\\/"}{print $1,$2}')"
|
|
case $1 in
|
|
add)
|
|
sed -i "/${_item}/d" "${INSTALLED_PACKAGES}"
|
|
echo "$2" >> ${INSTALLED_PACKAGES}
|
|
;;
|
|
delete)
|
|
sed -i "/${_item}/d" "${INSTALLED_PACKAGES}"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
leaf_update_environment() {
|
|
ldconfig
|
|
[ ! -r /etc/profile ] || source /etc/profile
|
|
}
|
|
|
|
leaf_prepare_package() {
|
|
local url sourcefile index _md5sum
|
|
distdir="${DIST_DIR}"
|
|
mkdir -pv "${distdir}"
|
|
pushd "${distdir}"
|
|
for index in "${!sources[@]}"; do
|
|
sourcefile="${sources[$index]}"
|
|
url="${urls[$index]}"
|
|
|
|
if [ -f "${sourcefile}" ]; then
|
|
echo "${sourcefile} exits, checking..."
|
|
_md5sum=$(md5sum ${sourcefile} | awk '{print $1}')
|
|
if [ "${_md5sum}" == "${md5sums[$index]}" ]; then
|
|
echo "md5sum match, skip ${sourcefile}."
|
|
else
|
|
echo "md5sum does not match, redownloading..."
|
|
rm -rf "${sourcefile}"
|
|
wget -O "${sourcefile}" "${url}"
|
|
fi
|
|
else
|
|
echo "Downloading ${sourcefile}..."
|
|
wget -O "${sourcefile}" "${url}"
|
|
fi
|
|
_md5sum=$(md5sum "${sourcefile}" | awk '{print $1}')
|
|
if [ "${_md5sum}" != "${md5sums[$index]}" ]; then
|
|
leaf_error "md5sums of ${sourcefile}(${_md5sum}) does not match with ${md5sums[$index]}!"
|
|
fi
|
|
done
|
|
popd
|
|
echo "Sources ready."
|
|
src_prepare
|
|
}
|
|
|
|
leaf_build_package() {
|
|
leaf_prepare_package
|
|
src_build
|
|
|
|
if ! src_check; then
|
|
if [ "${FORCE_INSTALL}" == "1" ]; then
|
|
echo -e "${RED_COLOR}* Tests failed, but is in force-install mode.${CLEAR_COLOR}"
|
|
else
|
|
leaf_error "Tests failed, please check. Aborting installation."
|
|
fi
|
|
fi
|
|
|
|
src_install
|
|
local _option
|
|
for _option in $(echo ${!BUILD_OPTIONS[*]}); do
|
|
if [[ x"${_option}" == x"strip" ]] && [[ x"${BUILD_OPTIONS[$_option]}" == x"1" ]]; then
|
|
leaf_strip_files
|
|
fi
|
|
if [[ x"${_option}" == x"libtool" ]] && [[ x"${BUILD_OPTIONS[$_option]}" == x"0" ]]; then
|
|
leaf_remove_libtool_files
|
|
fi
|
|
if [[ x"${_option}" == x"zipman" ]] && [[ x"${BUILD_OPTIONS[$_option]}" = x"1" ]]; then
|
|
leaf_compress_man_pages
|
|
fi
|
|
done
|
|
if [[ x"${ENABLE_DEBUG_TREE}" == x"true" ]]; then
|
|
[ ! -x /usr/bin/tree ] || /usr/bin/tree "${pkgdir}"
|
|
fi
|
|
}
|
|
|
|
leaf_install_package() {
|
|
# install need to be in fakeroot
|
|
leaf_build_package
|
|
# trace need to to in the same fakeroot
|
|
leaf_trace_package "${pkgdir}"
|
|
# ROOT starts
|
|
src_preinstall
|
|
leaf_merge_package "${pkgdir}"
|
|
src_postinstall
|
|
leaf_update_package_database add "${PKG_PREFIX}/${PKG_NAME}"
|
|
leaf_update_environment
|
|
# ROOT ends
|
|
echo -e "${GREEN_COLOR}* Package ${PKG_PREFIX}/${PKG_NAME} has been installed${CLEAR_COLOR}\n"
|
|
}
|
|
|
|
leaf_dirct-install_package() {
|
|
# install need to be in fakeroot
|
|
#leaf_build_package
|
|
# trace need to to in the same fakeroot
|
|
leaf_trace_package "${pkgdir}"
|
|
# ROOT starts
|
|
src_preinstall
|
|
leaf_merge_package "${pkgdir}"
|
|
src_postinstall
|
|
leaf_update_package_database add "${PKG_PREFIX}/${PKG_NAME}"
|
|
leaf_update_environment
|
|
# ROOT ends
|
|
echo -e "${GREEN_COLOR}* Package ${PKG_PREFIX}/${PKG_NAME} has been installed${CLEAR_COLOR}\n"
|
|
}
|
|
|
|
leaf_force-install_package(){
|
|
FORCE_INSTALL=1
|
|
leaf_install_package
|
|
}
|
|
|
|
leaf_remove_package() {
|
|
[ -n "$(grep "${PKG_PREFIX}/${PKG_NAME}" ${INSTALLED_PACKAGES})" ] || {
|
|
leaf_error "Package ${PKG_PREFIX}/${PKG_NAME} is NOT installed"
|
|
}
|
|
src_preremove
|
|
local _file _link _directory _etc_backup_path _relative_path _backup_etc=false
|
|
_etc_backup_path="/etc/.leaf_backup/${PKGNAME}_$(date +%Y%m%d%H%M%S)"
|
|
cat "${TRACE_DIR}/${PKG_PREFIX}/${PKG_NAME}/FILES" | while read -r _file; do
|
|
if [[ "${_file}" == /etc/* && -f "${_file}" ]]; then
|
|
_backup_etc=true
|
|
_relative_path="${_file#/etc/}"
|
|
mkdir -pv "${_etc_backup_path}/$(dirname "${_relative_path}")"
|
|
mv -v "${_file}" "${_etc_backup_path}/${_relative_path}"
|
|
else
|
|
rm -fv "${_file}"
|
|
fi
|
|
done
|
|
if [[ "${_backup_etc}" == true ]]; then
|
|
leaf_record_message "Found files in /etc, backuped to ${_etc_backup_path}."
|
|
fi
|
|
cat "${TRACE_DIR}/${PKG_PREFIX}/${PKG_NAME}/LINKS" | while read -r _link; do
|
|
[ ! -L "${_link}" ] || rm -fv "${_link}"
|
|
done
|
|
cat "${TRACE_DIR}/${PKG_PREFIX}/${PKG_NAME}/DIRS" | while read -r _directory; do
|
|
rmdir --ignore-fail-on-non-empty "${_directory}"
|
|
done
|
|
src_postremove
|
|
leaf_invoke_hooks remove
|
|
rm -rf "${TRACE_DIR}/${PKG_PREFIX}/${PKG_NAME}"
|
|
leaf_update_package_database delete "${PKG_PREFIX}/${PKG_NAME}"
|
|
leaf_update_environment
|
|
}
|
|
|
|
leaf_search_package() {
|
|
local _item _regex
|
|
for _item in "$@"; do
|
|
_regex+="${_item}\|"
|
|
done
|
|
_regex="${_regex:0:${#_regex}-2}"
|
|
find "${PKGBUILD_DIR}" -type f -regex ".*\(${_regex}\).*\.PKGBUILD" -printf "%P\n" | while read -r _item; do
|
|
echo "${_item%.PKGBUILD}"
|
|
done
|
|
}
|
|
|
|
leaf_show_package() {
|
|
source "${PKGBUILD_DIR}/${PKG_PREFIX}/${PKG_NAME}".PKGBUILD
|
|
echo "Package: ${pkgname}"
|
|
echo "Version: ${pkgver}"
|
|
echo "Description: ${pkgdesc}"
|
|
echo "Homepage: ${homepage}"
|
|
echo -e "License: ${license[@]}\n"
|
|
}
|
|
|
|
leaf_pack_package() {
|
|
leaf_build_package
|
|
pushd "${srcdir}" > /dev/null 2>&1
|
|
echo "${PKG_PREFIX}" > .PKG_PREFIX
|
|
install -m644 "${PKGBUILD_DIR}/${PKG_PREFIX}/${PKG_NAME}".PKGBUILD .PKGBUILD
|
|
install -dm755 "${BINARY_DIR}"
|
|
local _target="${BINARY_DIR}/${pkgname}-${pkgver}${BINARY_EXT}"
|
|
rm -fv "${_target}"
|
|
tar -I "${COMPRESS_PROG}" -cf "${_target}" "$(basename ${pkgdir})" .PKG{_PREFIX,BUILD}
|
|
popd > /dev/null 2>&1
|
|
}
|
|
|
|
leaf_unpack_package() {
|
|
srcdir="${TEMP_DIR}/$(basename ${1%.pkg.*})"
|
|
pkgdir="${srcdir}"/__pkgdir__
|
|
rm -rf "${srcdir}" && install -dm755 "${srcdir}" && cd "${srcdir}"
|
|
tar -xf $1 -C "${srcdir}"
|
|
source "${srcdir}"/.PKGBUILD
|
|
PKG_PREFIX="$(cat "${srcdir}"/.PKG_PREFIX)"
|
|
PKG_NAME="${pkgname}-${pkgver}"
|
|
install -Dm644 "${srcdir}"/.PKGBUILD "${PKGBUILD_DIR}/${PKG_PREFIX}/${PKG_NAME}".PKGBUILD
|
|
leaf_trace_package "${pkgdir}"
|
|
src_preinstall
|
|
leaf_merge_package "${pkgdir}"
|
|
src_postinstall
|
|
leaf_update_package_database add "${PKG_PREFIX}/${PKG_NAME}"
|
|
leaf_update_environment
|
|
echo -e "${GREEN_COLOR}* Package ${PKG_PREFIX}/${PKG_NAME} has been installed${CLEAR_COLOR}\n"
|
|
}
|
|
|
|
main $@
|