View previous topic :: View next topic |
Author |
Message |
thomasa88 Tux's lil' helper
Joined: 13 Apr 2005 Posts: 143 Location: Sweden
|
Posted: Wed Jun 08, 2005 11:50 am Post subject: Resume emerge when no resume file - continuemerge.pl |
|
|
I wrote this script because sometimes my computer just hangs when emerging and no resume-file is written, and when you do a --emptytree you dont want to start again from the beginning. Instead you want to continue from where it was before hanging. My script does that by skipping to the ebuild you want to start from. (maybe not the best gram. but the computer hung on emerge while I was writing this post the first time :S)
Comments and suggestions are welcome
edit.
The script has support for following namingformats (if more than one hit it will take the first)
cat-subcat/prg-ver
cat-subcat/prg
prg-ver
prg
Version 2 added (after v1, cronologhical )
Version 1.xx
This is the first and textbased version (with some colors )
Code: |
#!/usr/bin/perl
################################################################################
# File: continuemerge.pl
# Version: 1.09
# By: Thomas Axelsson 2005
# Description: Let's you resume an emerge -e when emerge can't resume (--resume)
################################################################################
#Let the user choose which ebuild to use
sub ChooseStartFrom #($fullList)
{
my($fullList,$startFrom)=($_[0]);
while(true)
{
print "Which ebuild do you want to \e[32mstart from?\e[0m\n";
print("1 = Show full merge list 2 = Show the last lines of emerge log\n\n");
print "\e[36m";
$startFrom=<STDIN>;
chomp($startFrom);
print "\e[0m\n\n";
if($startFrom eq "1")
{
print $fullList;
}
elsif($startFrom eq "2")
{
system("tail -n20 /var/log/emerge.log");
}
else
{
#done
last;
}
print "\n\n";
}
return $startFrom;
}
#Generate $fullList (to show user, instead of running emerge -p everytime) and $buildList (to pass to emerge)
sub GenList #($cmd)
{
my($cmd,$buildList,$fullList)=($_[0]);
#Get output from emerge -p
print "Generating lists with emerge...";
$fullList=`$cmd`;
print "Done.\n\n";
print "Parsing lists...";
#Remove anything that isn't an ebuild
$fullList=~s/^[^[].*$//mg;
$fullList=~s/\n{2,}/\n/g;
#We gonna do a list to show the user ($fullList) and when to pass to emerge ($buildList)
$buildList=$fullList;
#Fancy colors
$fullList=~s/\[ebuild.{7}\] //g;
$fullList=~s|^(.*?/)(.*?)(-[0-9])|\e[35m$1\e[32m$2\e[0m$3|mg;
#Make a list we can pass to emerge
$buildList=~s/\[ebuild.{7}\] /=/g;
$buildList=~s/\n/ /g;
$buildList=~s/ {2,}/ /g;
print "Done.\n\n";
return ($fullList,$buildList);
}
sub CheckPerms
{
#Is user root?
my($user)=`whoami`;
chomp($user);
if($user ne 'root')
{
#No. Then we have to exit
print "\e[31mError\e[0m: You must be \e[32mroot\e[0m to emerge!\n\n";
exit;
}
}
#Separate the output from what is written before
print "\n\n";
#Check if the user is root
CheckPerms;
#The main loop
while(true)
{
my($cmd,$startFrom,$fullList,$buildList,$correct);
#Ask the user what command he want to resume
print "What \e[32mcommand\e[0m did you run?\n";
print "\e[36memerge ";
$cmd=<STDIN>;
chomp($cmd);
#We don't want verbose output
$cmd=~s/-v( |$)|v([^ ])|(-[^ ]+)v/$1$2$3/g;
$cmd="emerge -p $cmd";
print "\e[0m\n\n";
#Get ebuild-lists from user input
($fullList,$buildList)=GenList($cmd);
#Loop until the user choose an existing ebuild
while(true)
{
#Ask the user where to start from
$startFrom=ChooseStartFrom($fullList);
print "Excluding packages before \e[32m$startFrom\e[0m...";
#Check if the ebuild is in the list
if($buildList!~m|[=/]$startFrom[- ]|)
{
#Ebuild doesnt exist, inform the user
print "\e[31mError\e[0m: ";
print "The package you have specified could not be found in the list\nWrite \e[32m1\e[0m to show the \e[32mpackages you can choose from\e[0m.\n\n";
#Let the user fill in the name again
redo;
}
#Remove all ebuilds before the one specified
$buildList=~s/(.* )(.*?${startFrom}.*? )//;
$buildList="$2$buildList";
#print "\e[31m$1\e[0m";
#print "\e[32m$buildList\e[0m";
print "Done.\n\n";
#Stop the loop when the user has chosen an existing ebuild
last;
}
#Output what will happen if the generated list gets emerged
print "These packages will be emerged:\n\n";
system("emerge -p $buildList");
#Ask the user if this is correct
print "\n\nIs this \e[32mcorrect\e[0m?[y] ";
$correct=<STDIN>;
chomp($correct);
#Check the answer from the user
if($correct eq "y" || $correct eq "Y" || $correct eq "")
{
#Do the emerge and stop the script
print "\n\nEmerging...\n\n";
system("emerge $buildList");
last;
}
else
{
#Insert some new lines and return to the beginning
print "\n\n\n\n";
}
}
|
edit.
1.09 - Replace die with exit, added check for verbose (emerge -v)
1.08 - Added whoami-check
1.07 - Replaced local with my
edit.
Version 2.xx
This is the second version, it uses dialog to show and get information.
2.01 - added -q when getting list from emerge
Code: |
#!/usr/bin/perl
################################################################################
# File: continuemerge2.pl
# Version: 2.01
# By: Thomas Axelsson 2005
# Description: Let's you resume an emerge when emerge can't resume (--resume)
################################################################################
sub MenuChooseStartFrom #(@fullList)
{
# my(@fullList,@fullListInfo,$startFrom,$defaultItem)=(@_);
#Try to figure out where the user want to start (this isnt good on memory if the file is big..)
#Lets make a block with a private array
{
#Read and reverse the emerge log
open(LOG,"</var/log/emerge.log");
my @emergeLog=reverse <LOG>;
close(LOG);
#Read every line until we find an ebuild in our list
LOGLOOP: foreach $line(@emergeLog)
{
#Sample: 1118255374: ::: completed emerge (37 of 40) net-misc/openssh-3.9_p1-r2 to /
if($line=~/[0-9]+: ::: completed emerge \([0-9]+ of [0-9]+\) (.+?\/.+?) to .*/)
{
#< is intended, we don't want to check the latest and try to add info to the next one
for($i=0;$i<$#fullList;$i++)
{
if($fullList[$i] eq $1)
{
$defaultItem=$fullList[$i+1];
$fullListInfo[$i+1]="<--- Guess";
last LOGLOOP;
}
}
}
}
}
for($i=0;$i<=$#fullList;$i++)
{
$fullList[$i]="\"$fullList[$i]\" \"$fullListInfo[$i]\"";
}
$fullList=join(" ",@fullList);
$startFrom=`dialog --stdout --ok-label Choose --cancel-label Exit --default-item "$defaultItem" --menu "Which ebuild do you want to start from?" 0 0 0 $fullList`;
}
#Generate @fullList (to show user, instead of running emerge -p everytime) and @buildList (to pass to emerge)
sub GenListArrays #($cmd)
{
# my($cmd,$buildList,@fullList)=($_[0]);
system("dialog --infobox \"Generating lists with emerge...\" 0 0");
#Get output from emerge -p
@fullList=`$cmd`;
system("dialog --infobox \"Parsing lists...\" 0 0");
#Remove anything that isn't an ebuild
@fullList=grep{
$_!~/^[^[].*$/;
} @fullList;
#Remove traling \n and \s
@fullList=map{
chomp($_);
$_=~s/\s+$//g;
$_;
} @fullList;
#We gonna do a list to show the user (@fullList) and when to pass to emerge (@buildList)
@buildList=@fullList;
#Remove unnecessary info
@fullList=map{
$_=~s/\[ebuild.{7}\] //;
$_;
} @fullList;
#Make a list we can pass to emerge
@buildList=map{
$_=~s/\[ebuild.{7}\] /=/;
$_;
} @buildList;
# return (@fullList,@buildList);
}
sub CheckPerms
{
#Is user root?
my($user)=`whoami`;
chomp($user);
if($user ne 'root')
{
#No. Then we have to exit
system("dialog --msgbox \"You must be root to run emerge!\" 0 0");
exit;
}
}
#Check if the user is root
CheckPerms;
#The main loop
while(true)
{
# my($cmd,$startFrom,@fullList,@buildList,$correct);
#Ask the user what command he want to resume
$cmd=`dialog --stdout --inputbox "What command did you run?" 0 0`;
#We don't want verbose output
$cmd=~s/-v( |$)|v([^ ])|(-[^ ]+)v/$1$2$3/g;
#Add "emerge"?
if($cmd!~/^\s*emerge/)
{
$cmd="emerge $cmd";
}
#Add --pretend and --quite
$cmd.=" -pq";
#Get ebuild-lists from user input
#($fullList,$buildList)=GenList($cmd);
GenListArrays($cmd);
#Ask the user where to start from
$startFrom=MenuChooseStartFrom(@fullList);
if($startFrom eq "")
{
last;
}
system("dialog --info \"Excluding packages before $startFrom...\" 0 0 ");
#Check if the ebuild is in the list
if((grep {$_=~$startFrom} @buildList)!=1)
{
#Ebuild doesnt exist, inform the user
system("dialog --msgbox \"Error: The package you have specified could not be found in the list :S\" 0 0");
exit;
}
#Remove all ebuilds before the one specified
{
my $keep=0;
@buildList=grep{
if(!$keep && $_=~/$startFrom/)
{
$keep=1;
}
if($keep)
{
1;
}
else
{
0;
}
} @buildList;
}
my $buildList='"'.join('" "" "',@buildList).'" ""';
#Output what will happen if the generated list gets emerged
#and ask if the list is correct
$correct=`dialog --stdout --ok-label Yes --cancel-label No --menu "This is the new merge list. Is it correct?" 0 0 0 $buildList`;
#Check the answer from the user
if($correct)
{
#Do the emerge and stop the script
print "\n\nEmerging...\n\n";
#system("emerge $buildList");
last;
}
else
{
#Let the loop rerun
}
}
|
_________________ - thomasa88
Last edited by thomasa88 on Sun Feb 05, 2006 1:24 pm; edited 3 times in total |
|
Back to top |
|
|
JoshFed n00b
Joined: 21 Jul 2003 Posts: 44 Location: Tacoma, WA USA
|
Posted: Thu Jun 09, 2005 3:52 am Post subject: |
|
|
Good thinkin. I don't know much about Perl, yet, but I'll check it out.
I try to do a "emerge --fetchonly X" first, then "emerge X." Especially for large ebuilds that have a lot of packages. |
|
Back to top |
|
|
thomasa88 Tux's lil' helper
Joined: 13 Apr 2005 Posts: 143 Location: Sweden
|
Posted: Wed Jun 22, 2005 11:35 am Post subject: |
|
|
Added V2 beta _________________ - thomasa88 |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|