functions: download set-cache set-mirror apt-install apt-remove begin charlie

Here are the changes, by line number:

- remove "-c", keep long version
- remove "-f" and "--file". I have never used this, and apt-get does does have
  it
- remove "-m", keep long version
- remove "--help", you can get help by just "apt-cyg"
- lowercase ARCH variable, typically uppercase is for exported variables
- use readonly variables where applicable
- remove setup.ini-save, I see no point in this, and setup.exe does not use it
- go back to using "[" over "[[", more portable
- declare all variables local in "begin" function, this will prevent creation of
  global variables. Child functions still have access to local variables, but
  the only fix to that is running every function in a subshell, which is also
  not ideal
- use "let" over "(("
- stop using awk ENVIRON array. This became a problem because the array is only
  populated with exported variables. We do not want variables being passed to
  child "apt-cyg" processes just to play nice with awk
- use "return" in functions instead of "exit", this will allow proper running of
  "charlie" function
- add "check-packages" to some functions
- stop creating "desc" files, you can parse this information out of setup.ini
  easy enough, and setup.exe does not create them either
- generate md5 file from setup.ini, this way you can use it with md5sum instead
  of stdin
- utilize "wget -rnH" to create directories
- stop running "type -P" when searching for a file with "apt-cyg search".
  apt-get does not do this and it could be confusing
- break "--cache" and "--mirror" out of the case statement and into their own
  functions. this will make the case statement less unwieldy
- write directly to "installed.db" using "awk -i inplace"
- function "charlie": this check for any leaked global variables and prints them
  to stdout just before the script finishes. this should help with debugging
This commit is contained in:
Steven Penny 2014-12-29 16:36:17 -06:00
parent c325aee5a6
commit cc9b2bdf0d
1 changed files with 203 additions and 235 deletions

438
apt-cyg
View File

@ -43,10 +43,8 @@ Commands:
searchall Search for a filename from all available packages searchall Search for a filename from all available packages
Options: Options:
-c, --cache <dir> set cache --cache <dir> set cache
-f, --file <file> read package names from file --mirror <url> set mirror
-m, --mirror <url> set mirror
--help
--version --version
+ +
@ -58,7 +56,7 @@ The MIT License (MIT)
Copyright (c) 2005-9 Stephen Jungels Copyright (c) 2005-9 Stephen Jungels
+ +
ARCH=${HOSTTYPE/i6/x} readonly usage version
function wget { function wget {
if command wget -h &>/dev/null if command wget -h &>/dev/null
@ -75,26 +73,26 @@ function find-workspace {
# default working directory and mirror # default working directory and mirror
# work wherever setup worked last, if possible # work wherever setup worked last, if possible
cache=$(awk ' readonly cache=$(awk '
/last-cache/ { /last-cache/ {
getline getline
print $1 print $1
} }
' /etc/setup/setup.rc | cygpath -f-) ' /etc/setup/setup.rc | cygpath -f-)
mirror=$(awk ' readonly mirror=$(awk '
/last-mirror/ { /last-mirror/ {
getline getline
print $1 print $1
} }
' /etc/setup/setup.rc) ' /etc/setup/setup.rc)
mirrordir=$(sed ' readonly mirrordir=$(sed '
s / %2f g s / %2f g
s : %3a g s : %3a g
' <<< "$mirror") ' <<< "$mirror")
mkdir -p "$cache/$mirrordir/$ARCH" mkdir -p "$cache/$mirrordir/$arch"
cd "$cache/$mirrordir/$ARCH" cd "$cache/$mirrordir/$arch"
if [ -e setup.ini ] if [ -e setup.ini ]
then then
return 0 return 0
@ -105,22 +103,16 @@ function find-workspace {
} }
function get-setup { function get-setup {
touch setup.ini if wget -N $mirror/$arch/setup.bz2
mv setup.ini setup.ini-save
wget -N $mirror/$ARCH/setup.bz2
if [ -e setup.bz2 ]
then then
bunzip2 setup.bz2 bunzip2 setup.bz2
mv setup setup.ini mv setup setup.ini
echo Updated setup.ini echo Updated setup.ini
else
echo Error updating setup.ini, reverting
mv setup.ini-save setup.ini
fi fi
} }
function check-packages { function check-packages {
if [[ $pks ]] if [ "$pks" ]
then then
return 0 return 0
else else
@ -147,32 +139,31 @@ function apt-update {
function apt-category { function apt-category {
check-packages check-packages
find-workspace find-workspace
for pkg in "${pks[@]}" for vas in "${pks[@]}"
do do
awk ' awk '
$1 == "@" { $1 == "@" {
pck = $2 pck = $2
} }
$1 == "category:" && $0 ~ query { $1 == "category:" && $0 ~ vas {
print pck print pck
} }
' query="$pks" setup.ini ' vas="$vas" setup.ini
done done
} }
function apt-list { function apt-list {
find-workspace find-workspace
local sbq for vas in "${pks[@]}"
for pkg in "${pks[@]}"
do do
(( sbq++ )) && echo let sbq++ && echo
info Searching for installed packages matching "$pkg": info Searching for installed packages matching "$vas":
awk 'NR>1 && $1~ENVIRON["pkg"] && $0=$1' /etc/setup/installed.db awk 'NR>1 && $1~vas && $0=$1' vas="$vas" /etc/setup/installed.db
echo echo
info Searching for installable packages matching "$pkg": info Searching for installable packages matching "$vas":
awk '$1 ~ ENVIRON["pkg"] && $0 = $1' RS='\n\n@ ' FS='\n' setup.ini awk '$1~vas && $0=$1' RS='\n\n@ ' FS='\n' vas="$vas" setup.ini
done done
(( sbq )) && return let sbq && return
info The following packages are installed: info The following packages are installed:
awk 'NR>1 && $0=$1' /etc/setup/installed.db awk 'NR>1 && $0=$1' /etc/setup/installed.db
} }
@ -180,41 +171,40 @@ function apt-list {
function apt-listfiles { function apt-listfiles {
check-packages check-packages
find-workspace find-workspace
local pkg sbq for vas in "${pks[@]}"
for pkg in "${pks[@]}"
do do
(( sbq++ )) && echo let sbq++ && echo
if [ ! -e /etc/setup/"$pkg".lst.gz ] if [ ! -e /etc/setup/"$vas".lst.gz ]
then then
download "$pkg" download || return
fi fi
gzip -cd /etc/setup/"$pkg".lst.gz gzip -cd /etc/setup/"$vas".lst.gz
done done
} }
function apt-show { function apt-show {
find-workspace find-workspace
check-packages check-packages
for pkg in "${pks[@]}" for vas in "${pks[@]}"
do do
(( notfirst++ )) && echo let sbq++ && echo
awk ' awk '
$1 == query { $1 == vas {
print print
fd++ fd++
} }
END { END {
if (! fd) if (! fd)
print "Unable to locate package " query print "Unable to locate package", vas
} }
' RS='\n\n@ ' FS='\n' query="$pkg" setup.ini ' RS='\n\n@ ' FS='\n' vas="$vas" setup.ini
done done
} }
function apt-depends { function apt-depends {
find-workspace find-workspace
check-packages check-packages
for pkg in "${pks[@]}" for vas in "${pks[@]}"
do do
awk ' awk '
@include "join" @include "join"
@ -226,7 +216,7 @@ function apt-depends {
reqs[apg][z-1] = $z reqs[apg][z-1] = $z
} }
END { END {
prpg(ENVIRON["pkg"]) prpg(vas)
} }
function smartmatch(small, large, values) { function smartmatch(small, large, values) {
for (each in large) for (each in large)
@ -242,13 +232,14 @@ function apt-depends {
prpg(reqs[fpg][each]) prpg(reqs[fpg][each])
delete spath[length(spath)] delete spath[length(spath)]
} }
' setup.ini ' vas="$vas" setup.ini
done done
} }
function apt-rdepends { function apt-rdepends {
check-packages
find-workspace find-workspace
for pkg in "${pks[@]}" for vas in "${pks[@]}"
do do
awk ' awk '
@include "join" @include "join"
@ -260,7 +251,7 @@ function apt-rdepends {
reqs[$z][length(reqs[$z])+1] = apg reqs[$z][length(reqs[$z])+1] = apg
} }
END { END {
prpg(ENVIRON["pkg"]) prpg(vas)
} }
function smartmatch(small, large, values) { function smartmatch(small, large, values) {
for (each in large) for (each in large)
@ -276,89 +267,77 @@ function apt-rdepends {
prpg(reqs[fpg][each]) prpg(reqs[fpg][each])
delete spath[length(spath)] delete spath[length(spath)]
} }
' setup.ini ' vas="$vas" setup.ini
done done
} }
function apt-download { function apt-download {
check-packages check-packages
find-workspace find-workspace
local pkg sbq for vas in "${pks[@]}"
for pkg in "${pks[@]}"
do do
(( sbq++ )) && echo let sbq++ && echo
download "$pkg" download
done done
} }
function download { function download {
local pkg digest digactual # look for package and save md5 file
pkg=$1
# look for package and save desc file
awk '$1 == pc' RS='\n\n@ ' FS='\n' pc=$pkg setup.ini > desc
if [ ! -s desc ]
then
echo Unable to locate package $pkg
exit 1
fi
# download and unpack the bz2 or xz file # download and unpack the bz2 or xz file
# pick the latest version, which comes first # pick the latest version, which comes first
set -- $(awk '$1 == "install:"' desc) awk '
if (( ! $# )) $1 == "@" {
c = $2
}
$1 == "install:" && c == vas {
print $4, $2
exit
}
' vas="$vas" setup.ini > md5.sum
if [ ! -s md5.sum ]
then then
echo 'Could not find "install" in package description: obsolete package?' warn Unable to locate package $vas
exit 1 return 1
fi fi
dn=$(dirname $2) read _ acv < md5.sum
bn=$(basename $2)
# check the md5 # check the md5
digest=$4 mv md5.sum ..
mkdir -p $cache/$mirrordir/$dn cd ..
cd $cache/$mirrordir/$dn if ! test -e $acv || ! md5sum -c md5.sum
if ! test -e $bn || ! md5sum -c <<< "$digest $bn"
then then
wget -O $bn $mirror/$dn/$bn wget -rnH $mirror/$acv
md5sum -c <<< "$digest $bn" || exit md5sum -c md5.sum || return
fi fi
tar tf $bn | gzip > /etc/setup/"$pkg".lst.gz tar tf $acv | gzip > /etc/setup/"$vas".lst.gz
cd ~-
mv desc $cache/$mirrordir/$dn
echo $dn $bn > /tmp/dwn
} }
function apt-search { function apt-search {
check-packages check-packages || return
echo Searching downloaded packages... echo Searching downloaded packages...
for pkg in "${pks[@]}" for vas in "${pks[@]}"
do do
key=$(type -P "$pkg" | sed s./..) for mft in /etc/setup/*.lst.gz
[[ $key ]] || key=$pkg
for manifest in /etc/setup/*.lst.gz
do do
if gzip -cd $manifest | grep -q "$key" if gzip -cd $mft | grep -q "$vas"
then then
package=$(sed ' awk '$0=$4' FS='[./]' <<< $mft
s,/etc/setup/,,
s,.lst.gz,,
' <<< $manifest)
echo $package
fi fi
done done
done done
} }
function apt-searchall { function apt-searchall {
cd /tmp check-packages
for pkg in "${pks[@]}" cd /etc/setup
for vas in "${pks[@]}"
do do
printf -v qs 'text=1&arch=%s&grep=%s' $ARCH "$pkg" printf -v qry 'text=1&arch=%s&grep=%s' $arch "$vas"
wget -O matches cygwin.com/cgi-bin2/package-grep.cgi?"$qs" wget -O matches cygwin.com/cgi-bin2/package-grep.cgi?"$qry"
awk ' awk '
{ {
if (NR == 1) if (NR == 1)
@ -373,76 +352,105 @@ function apt-searchall {
done done
} }
function set-cache {
if [ "$1" ]
then
vas=$(cygpath -aw "$1")
awk -i inplace '
1
/last-cache/ {
getline
print "\t" vas
}
' vas="${vas//\\/\\\\}" /etc/setup/setup.rc
echo Cache set to "$vas"
else
warn No path provided, exiting
fi
}
function set-mirror {
if [ "$1" ]
then
awk -i inplace '
1
/last-mirror/ {
getline
print "\t" vas
}
' vas="$1" /etc/setup/setup.rc
echo Mirror set to "$1"
else
warn No URL provided, exiting
fi
}
function apt-install { function apt-install {
check-packages check-packages
find-workspace find-workspace
local pkg dn bn requires wr package sbq script for vas in "${pks[@]}"
for pkg in "${pks[@]}"
do do
if grep -q "^$pkg " /etc/setup/installed.db if grep -q "^$vas " /etc/setup/installed.db
then then
echo Package $pkg is already installed, skipping echo Package $vas is already installed, skipping
continue continue
fi fi
(( sbq++ )) && echo let sbq++ && echo
echo Installing $pkg echo Installing $vas
download $pkg download || return
read dn bn </tmp/dwn
echo Unpacking... echo Unpacking...
cd $cache/$mirrordir/$dn tar -x -C / -f $acv
tar -x -C / -f $bn cd ~-
# update the package database # update the package database
awk ' awk -e '
ins != 1 && pkg < $1 { {
print pkg, bz, 0 foo[$0]
ins = 1
} }
1 ENDFILE {
END { $1 = vas
if (ins != 1) print pkg, bz, 0 $2 = acv
$3 = 0
foo[$0]
asorti(foo)
for (bar in foo)
print foo[bar]
} }
' pkg="$pkg" bz=$bn /etc/setup/installed.db > /tmp/awk.$$ ' -i inplace vas="$vas" acv=$acv /etc/setup/installed.db
mv /etc/setup/installed.db /etc/setup/installed.db-save
mv /tmp/awk.$$ /etc/setup/installed.db
# recursively install required packages # recursively install required packages
requires=$(awk '$1=="requires", $0=$2' FS=': ' desc) awk '
cd ~- $1 == "@" {
wr=0 c = $2
if [[ $requires ]] }
then $1 == "requires:" && c == vas {
echo Package $pkg requires the following packages, installing: print
echo $requires exit
for package in $requires }
do ' vas="$vas" setup.ini > deps.ini
if grep -q "^$package " /etc/setup/installed.db if [ -s deps.ini ]
then
echo Package $package is already installed, skipping
continue
fi
apt-cyg install --noscripts $package || (( wr++ ))
done
fi
if (( wr ))
then then
read _ rqs < deps.ini
echo Package $vas requires the following packages, installing:
echo $rqs
apt-cyg install --deps $rqs ||
info some required packages did not install, continuing info some required packages did not install, continuing
fi fi
# run all postinstall scripts # run all postinstall scripts
(( noscripts )) && continue let dps && continue
find /etc/postinstall -name '*.sh' | while read script find /etc/postinstall -name '*.sh' | while read script
do do
echo Running $script echo Running $script
$script $script
mv $script $script.done mv $script $script.done
done done
echo Package $pkg installed echo Package $vas installed
done done
} }
@ -451,21 +459,21 @@ function apt-remove {
check-packages check-packages
cd /etc cd /etc
cygcheck awk bash bunzip2 grep gzip mv sed tar xz > setup/essential.lst cygcheck awk bash bunzip2 grep gzip mv sed tar xz > setup/essential.lst
for pkg in "${pks[@]}" for vas in "${pks[@]}"
do do
if ! grep -q "^$pkg " setup/installed.db if ! grep -q "^$vas " setup/installed.db
then then
echo Package $pkg is not installed, skipping echo Package $vas is not installed, skipping
continue continue
fi fi
if [ ! -e setup/"$pkg".lst.gz ] if [ ! -e setup/"$vas".lst.gz ]
then then
warn Package manifest missing, cannot remove $pkg. Exiting warn Package manifest missing, cannot remove $vas. Exiting
exit 1 return 1
fi fi
gzip -dk setup/"$pkg".lst.gz gzip -dk setup/"$vas".lst.gz
awk ' awk '
NR == FNR { NR == FNR {
if ($NF) ess[$NF] if ($NF) ess[$NF]
@ -474,126 +482,74 @@ function apt-remove {
$NF in ess { $NF in ess {
exit 1 exit 1
} }
' FS='[/\\\\]' setup/{essential,$pkg}.lst ' FS='[/\\\\]' setup/{essential,$vas}.lst
esn=$? esn=$?
if [ $esn = 0 ] if [ $esn = 0 ]
then then
echo Removing $pkg echo Removing $vas
if [ -e preremove/"$pkg".sh ] if [ -e preremove/"$vas".sh ]
then then
preremove/"$pkg".sh preremove/"$vas".sh
rm preremove/"$pkg".sh rm preremove/"$vas".sh
fi fi
mapfile dt < setup/"$pkg".lst mapfile mft < setup/"$vas".lst
for each in ${dt[*]} for emt in ${mft[*]}
do do
[ -f /$each ] && rm /$each [ -f /$emt ] && rm /$emt
done done
for each in ${dt[*]} for emt in ${mft[*]}
do do
[ -d /$each ] && rmdir --i /$each [ -d /$emt ] && rmdir --i /$emt
done done
rm -f setup/"$pkg".lst.gz postinstall/"$pkg".sh.done rm -f setup/"$vas".lst.gz postinstall/"$vas".sh.done
awk -i inplace '$1 != ENVIRON["pkg"]' setup/installed.db awk -i inplace '$1 != vas' vas="$vas" setup/installed.db
echo Package $pkg removed echo Package $vas removed
fi fi
rm setup/"$pkg".lst rm setup/"$vas".lst
if [ $esn = 1 ] if [ $esn = 1 ]
then then
warn apt-cyg cannot remove package $pkg, exiting warn apt-cyg cannot remove package $vas, exiting
exit 1 return 1
fi fi
done done
} }
if [ -p /dev/stdin ] function begin {
then local acv dps emt esn mft pks qry rqs sbq tsk vas arch cache mirror mirrordir
mapfile -t pks if [ -p /dev/stdin ]
fi then
mapfile -t pks
fi
# process options # process options
while (( $# )) while let $#
do do
case "$1" in case "$1" in
--mirror | -m) --mirror)
awk -i inplace ' set-mirror "$2"
1 return
/last-mirror/ {
getline
print "\t" rpc
}
' rpc="$2" /etc/setup/setup.rc
shift 2
;; ;;
--cache | -c) --cache)
rpc=$(cygpath -aw "$2" | sed 's \\ \\\\ g') set-cache "$2"
awk -i inplace ' return
1
/last-cache/ {
getline
print "\t" rpc
}
' rpc="$rpc" /etc/setup/setup.rc
shift 2
;; ;;
--noscripts) --deps)
noscripts=1 dps=1
shift shift
;; ;;
--help)
printf %s "${usage[@]}"
exit 0
;;
--version) --version)
printf %s "${version[@]}" printf %s "${version[@]}"
exit 0 return
;; ;;
--file | -f) list | remove | update | install | download | listfiles |\
if [[ $2 ]] show | search | depends | category | rdepends | searchall )
then tsk=$1
mf=$2
if [ -f "$mf" ]
then
mapfile -t pks < "$mf"
else
echo File "$mf" not found, skipping
fi
shift
else
info No file name provided, ignoring $1
fi
shift
;;
update)
command=$1
shift
;;
install \
| remove \
| download \
| show \
| depends \
| rdepends \
| list \
| category \
| listfiles \
| search \
| searchall)
if [[ $command ]]
then
pks+=("$1")
else
command=$1
fi
shift shift
;; ;;
@ -603,13 +559,25 @@ do
;; ;;
esac esac
done done
if type -t apt-$tsk | grep -q function
then
readonly arch=${HOSTTYPE/i6/x}
apt-$tsk
else
printf %s "${usage[@]}"
fi
}
set -a function charlie {
cd /etc/setup
compgen -v > $1.lst
if [ $1 = fin ]
then
comm -3 {start,fin}.lst
fi
}
if type -t apt-$command | grep -q function charlie start
then begin "$@"
apt-$command charlie fin
else
printf %s "${usage[@]}"
fi