I for one have had 4 or 5 different emerge processes running all download/compiling different things in the past in seperate windows with NO problems whatsoever.
This BASH script simply makes sure that the compiles don't get ahead of the file downloads.
Known Problems (as of v0.16*)
Each package that you pass is emerged invididually and added to the world file, dependencies are NOT handled as emerge itself handles them (ie, not adding them to world file). This is a side-effect of the looping that I just discovered (ie, it's a bug in qemerge) but haven't though of an easy fix for yet. Meanwhile if you're only emerging dependencies you can pass the --oneshot parameter which qemerge now does understand... Sorry for this, any thoughts on an easy way to fix this would be welcome. Update 3-06: Solution is in my head... just need to turn it into code...
Updates
v0.02 - now will die if the compiling emerge process ends with an error
v0.10 - added status bar to top of screen detailing emerge and download progress
v0.15
- added name and version to status bar
can now be used as a wrapper script for emerge (ie, figures out if you're wanting emerge for some of it's options and calls it, otherwises does what it does best, emerge and download)
v0.151 - fix bug in sed editing of emerge output
v0.152 - add "info" to options that need to go directly to emerge
v0.16 - understands --oneshot option now
v0.161 - understand all options in man emerge and when to handle compiles/downloads and when to let emerge do the work (ie, when you've passed options that don't really have to do with compiling or downloading and using semerge as a full-fledged wrapper for emerge)
Everyone, let me know if you like it, want more, etc...
semerge v0.161
Code: Select all
#!/bin/bash
source /sbin/functions.sh
# the folder to store working files
TEMP=~/.semerge
EMERGE=/usr/bin/emerge
set_scroll()
{
#echo "from: $1 to: $2"
echo -en "\e[${1};${2}r\e[?4h";
}
save_cursor() { echo -en "\e7"; }
restore_cursor() { echo -en "\e8"; }
cursor_to() { echo -en "\e[$2;$1H"; }
erase_line() { echo -en "\e[2K"; }
download_files()
{
i=1;
total=`count_ebuilds $@`;
for ebuild in $@; do
update_dl_status "($i of $total) Fetching files for ${ebuild}..."
$EMERGE -f "=${ebuild}" 2>/dev/null >/dev/null
touch $TEMP/${ebuild/\//_}.complete
i=$(($i+1))
done
update_dl_status "Downloads complete..."
}
is_downloaded()
{
#convert the slash into an underscore
local ebuild=${1/\//_};
if [ -e $TEMP/${ebuild}.complete ]; then
return 0;
else
return 1;
fi
}
count_ebuilds()
{
i=0;
for x in $@; do
i=$(($i+1));
done
echo "$i"
}
setup_status_bar()
{
echo; echo;
save_cursor
set_scroll 4 80
cursor_to 1 1; erase_line
cursor_to 1 2; erase_line
cursor_to 1 3; erase_line
echo -en "--------------------------------\e[7m[ semerge v0.16 ]\e[0m--------------------------------"
restore_cursor
}
update_dl_status()
{
save_cursor
cursor_to 1 1
erase_line
einfo $@
restore_cursor
}
update_emerge_status()
{
save_cursor
cursor_to 1 2
erase_line
einfo $@
restore_cursor
}
start_compiles()
{
i=1;
total=`count_ebuilds $@`;
for ebuild in $@; do
# are the files for the ebuild downloaded
is_downloaded ${ebuild}
while [ $? != 0 ]; do
sleep 2s;
is_downloaded ${ebuild}
done
update_emerge_status "($i of $total) Emerging ${ebuild}..."
einfo "$EMERGE $EMERGE_OPTS \"=${ebuild}\""
einfo "($i of $total) Emerging ${ebuild}..."
$EMERGE $EMERGE_OPTS "=${ebuild}"
if [ $? != 0 ]; then
eerror "emerge ${ebuild}"
eerror " - has exited with an error"
echo
eerror "qemerge is exiting as well"
exit 1
fi
i=$(($i+1));
done
}
get_ebuilds()
{
all=`$EMERGE $@ -p | grep "\[ebuild " | sed -e "s/\[ebuild[^]]*] //" | awk '{print $1}'`
echo ${all}
return ${result}
}
clean_up()
{
for ebuild in $@; do
rm -f $TEMP/${ebuild/\//_}.complete
done
save_cursor; set_scroll 1 1000; restore_cursor
}
EMERGE_OPTS=""
is_emerge_options()
{
result=0
while [ ${#} -gt 0 ]; do
a=${1}
shift
case "${a}" in
--oneshot|--nodeps|--buildpkg|-b|--usepkg|-k|-verbose|-v)
# these options should be passed each time emerge is executed
EMERGE_OPTS="$EMERGE_OPTS ${a}"
;;
--deep|--emptytree|-e|--onlydeps|-o)
# these simply possibly add or change which packages
# emerge returns, these are allowed
;;
clean|depclean|help|info|inject|prune|rsync|search|sync|unmerge)
result=1
;;
-*)
result=1
;;
esac
done
return ${result}
}
is_emerge_options $@
if [ $? != 0 ]; then
$EMERGE $@
exit
fi
# make sure working folder it exists
mkdir -p $TEMP
# get the ebuilds we'll be building
ebuilds=`get_ebuilds $@`
if [ -z "${ebuilds}" ]; then
$EMERGE $@
exit
fi
# startup stuff
clean_up ${ebuilds}
setup_status_bar
# start the downloads in the background (one at a time)
download_files ${ebuilds} &
# start compiling
start_compiles ${ebuilds}
# clean up our state tracking files
clean_up ${ebuilds}



