[pacman-dev] bacman
Hello, as I wanted to learn a little about general shell scripting, with the great help of shining and Allan I wrote this script which rebuilds a package using the meta data in the pacman database and actual system files. Forum discussion: http://bbs.archlinux.org/viewtopic.php?id=49168 Script: http://pastebin.com/m3f763692 Thanks for your time, Carlo "carlocci" Bersani PS: Here's the patch for the autocompletition --- pacman 2008-05-29 23:49:22.000000000 +0200 +++ pacman.new 2008-05-29 23:48:58.000000000 +0200 @@ -361,3 +361,13 @@ } complete -o filenames -F _pacman pacman +## bacman completition + +_bacman () +{ + cur=${COMP_WORDS[COMP_CWORD]} + _installed_pkgs +} + +complete -o filenames -F _bacman bacman +
On Thu, May 29, 2008 at 4:55 PM, carlocci <carlocci@gmail.com> wrote:
Hello, as I wanted to learn a little about general shell scripting, with the great help of shining and Allan I wrote this script which rebuilds a package using the meta data in the pacman database and actual system files. Forum discussion: http://bbs.archlinux.org/viewtopic.php?id=49168 Script: http://pastebin.com/m3f763692 Thanks for your time,
Would you mind submitting it inline so we can comment on it here? Thanks, -Dan
On 5/29/08, Dan McGee <dpmcgee@gmail.com> wrote:
Forum discussion: http://bbs.archlinux.org/viewtopic.php?id=49168 Script: http://pastebin.com/m3f763692 Thanks for your time,
Would you mind submitting it inline so we can comment on it here?
I hope I understood what you meant: here's the script #!/bin/bash # # bacman: recreate a package from a running system # This script rebuilds an already installed package using metadata # stored into the pacman database and system files # # (c) 2008 - locci <carlocci_at_gmail_dot_com> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # readonly progname="bacman" readonly progver="0.1.2" # # User Friendliness # function usage(){ echo "This program recreates a package using pacman's db and system files" echo "Usage: $progname <installed package name>" echo "Example: $progname kernel26" } if [ $# -ne 1 ] ; then usage exit 1 fi if [ "$1" = "--help" -o "$1" = "-h" ] ; then usage exit 0 fi if [ "$1" = "--version" -o "$1" = "-v" ]; then echo "$progname version $version" echo "Copyright (C) 2008 locci" exit 0 fi # # Setting environmental variables # eval $(sed -nre 's:[[:space:]]*(DBPath|CacheDir)[[:space:]]*=[[:space:]]*([[:print:]]*):\1="\2":p' /etc/pacman.conf) pac_db="${DBPath:-/var/lib/pacman/}/local" pac_cache="${CacheDir:-/var/cache/pacman/pkg/}" pkg_name="$1" pkg_dir="$(echo $pac_db/$pkg_name-[0-9]*)" eval $(sed -nre 's:[[:space:]]*(CARCH|PKGDEST|PACKAGER)[[:space:]]*=[[:space:]]*([[:print:]]*):\1=\2:p' /etc/makepkg.conf) pkg_arch=${CARCH:-'unknown'} pkg_dest="${PKGDEST:-$PWD}" pkg_pkger=${PACKAGER:-'Unknown Packager'} pkg_namver="${pkg_dir##*/}" # # Checks everything is in place # if [ ! -d "$pac_db" ] ; then echo Error: pacman database directory ${pac_db} not found exit 1 fi if [ ! -d "$pac_cache" ] ; then echo Warning: pacman pkg cache directory ${pac_cache} not found unset pac_cache fi if [ ! -d "$pkg_dir" ] ; then echo Error: package ${pkg_name} not found in pacman database exit 1 fi if [ -n "$pac_cache" ] && [ -f "$pac_cache"/"$pkg_namver"*.tar.gz ] ; then echo Warning: the package for ${pkg_name} already exists in your pacman cache # read -n 1 -p 'Do you want to fetch it instead? (y/N) ' # case $REPLY in # y|Y) # cp "$pac_cache"/"$pkg_namver"*.pkg.tar.gz "$pkg_dest" # exit 0 # ;; # *) echo "" # ;; # esac fi # # Begin # echo Package: ${pkg_namver} work_dir=$(mktemp -d -p /tmp) cd $work_dir || exit 1 # # File copying # echo Copying package files... cat "$pkg_dir"/files | while read i; do if [ -z "$i" ] ; then continue fi if [[ "$i" =~ %[A-Z]*% ]] ; then current=$i continue fi case $current in %FILES%) if [ -d "/$i" ]; then mkdir "$i" elif [ -f "/$i" ]; then install -D "/$i" "$i" else echo "/$i" is missing: this might result in a broken package fi ;; esac pkg_size=$(du -sb | awk '{print $1}') done echo Adding install commands and changelogs, if any... if [ -f "$pkg_dir/install" ] ; then cp "$pkg_dir/install" "$work_dir/.INSTALL" fi if [ -f $pkg_dir/changelog ] ; then cp "$pkg_dir/changelog" "$work_dir/.CHANGELOG" fi # # .PKGINFO stuff # echo echo Generating .PKGINFO metadata... echo "# Generated by $progname $progver" > .PKGINFO echo "# $(LC_ALL=C date)" >> .PKGINFO echo "#" >> .PKGINFO cat "$pkg_dir"/{desc,files,depends} | while read i; do if [[ -z "$i" ]]; then continue; fi if [[ "$i" =~ %[A-Z]*% ]] ; then current=$i continue fi case "$current" in # desc %NAME%) echo "pkgname = $i" >> .PKGINFO ;; %VERSION%) echo "pkgver = $i" >> .PKGINFO ;; %DESC%) echo "pkgdesc = $i" >> .PKGINFO ;; %URL%) echo "url = $i" >> .PKGINFO ;; %LICENSE%) echo "license = $i" >> .PKGINFO ;; %ARCH%) echo "arch = $i" >> .PKGINFO ;; %BUILDDATE%) echo "builddate = $(date -u "+%s")" >> .PKGINFO ;; %PACKAGER%) echo "packager = $pkg_pkger" >> .PKGINFO ;; %SIZE%) echo "size = $pkg_size" >> .PKGINFO ;; %GROUPS%) echo "group = $i" >> .PKGINFO ;; %REPLACES%) echo "replaces = $i" >> .PKGINFO ;; # files %BACKUP%) # strip the md5sum after the tab echo "backup = ${i%% *}" >> .PKGINFO ;; # depends %DEPENDS%) echo "depend = $i" >> .PKGINFO ;; %OPTDEPENDS%) echo "optdepend = $i" >> .PKGINFO ;; %CONFLICTS%) echo "conflict = $i" >> .PKGINFO ;; %PROVIDES%) echo "provides = $i" >> .PKGINFO ;; %FORCE%) echo "force = true" >> .PKGINFO ;; esac done # # Generate the package # echo echo Generating the package... ret=0 bsdtar -czf "$pkg_dest/$pkg_namver-$pkg_arch.tar.gz" $(ls -A) || ret=$? if [ $ret -ne 0 ]; then echo Error: Unable to write package to $pkg_dest echo Maybe the disk is full or you do not have write access exit 1 fi rm -rf $work_dir exit 0 # vim: set ts=2 sw=2 noet:
carlocci wrote:
<snip> # # File copying # echo Copying package files...
cat "$pkg_dir"/files | while read i; do if [ -z "$i" ] ; then continue fi
if [[ "$i" =~ %[A-Z]*% ]] ; then current=$i continue fi
case $current in %FILES%) if [ -d "/$i" ]; then mkdir "$i" elif [ -f "/$i" ]; then install -D "/$i" "$i" else echo "/$i" is missing: this might result in a broken package fi ;; esac pkg_size=$(du -sb | awk '{print $1}') done
echo Adding install commands and changelogs, if any... if [ -f "$pkg_dir/install" ] ; then cp "$pkg_dir/install" "$work_dir/.INSTALL" fi if [ -f $pkg_dir/changelog ] ; then cp "$pkg_dir/changelog" "$work_dir/.CHANGELOG" fi
<snip>
The setting of the pkg_size variable needs to be outside that loop/subshell pipe (it currently does not work). Another point, the whole file copying bit should probably be inside a fakeroot and using "cp -pd" in order to get file permissions right. Probably want to check directory permissions too. Will still have problems with files that can't be read by a user by the error messages makes it obvious what happened. Maybe should catch that error too... Allan
Here is my latest adjustment to the bacman script including all changes mentioned so far in the thread. Remaining issues are permissions: 1) Group information is lost 2) Directory permissions are always 755 3) Sometimes bails when user does not have permission to read file. I added a catch for this but it could probably be fixed with the above. #!/bin/bash # # bacman: recreate a package from a running system # This script rebuilds an already installed package using metadata # stored into the pacman database and system files # # (c) 2008 - locci <carlocci_at_gmail_dot_com> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # readonly progname="bacman" readonly progver="0.1.2" # # User Friendliness # function usage(){ echo "This program recreates a package using pacman's db and system files" echo "Usage: $progname <installed package name>" echo "Example: $progname kernel26" } if [ $# -ne 1 ] ; then usage exit 1 fi if [ "$1" = "--help" -o "$1" = "-h" ] ; then usage exit 0 fi if [ "$1" = "--version" -o "$1" = "-v" ]; then echo "$progname version $version" echo "Copyright (C) 2008 locci" exit 0 fi # # Setting environmental variables # if [ ! -r /etc/pacman.conf ]; then echo Error: unable to read /etc/pacman.conf exit 1 fi eval $(awk '/DBPath/ {print $1$2$3}' /etc/pacman.conf) pac_db="${DBPath:-/var/lib/pacman/}/local" if [ ! -r /etc/makepkg.conf ]; then echo Error: unable to read /etc/makepkg.conf exit 1 fi source "/etc/makepkg.conf" if [ -r ~/.makepkg.conf ]; then source ~/.makepkg.conf fi pkg_arch=${CARCH:-'unknown'} pkg_dest="${PKGDEST:-$PWD}" pkg_pkger=${PACKAGER:-'Unknown Packager'} pkg_name="$1" pkg_dir="$(echo $pac_db/$pkg_name-[0-9]*)" pkg_namver="${pkg_dir##*/}" # # Checks everything is in place # if [ ! -d "$pac_db" ] ; then echo Error: pacman database directory ${pac_db} not found exit 1 fi if [ ! -d "$pkg_dir" ] ; then echo Error: package ${pkg_name} not found in pacman database exit 1 fi # # Begin # echo Package: ${pkg_namver} work_dir=$(mktemp -d -p /tmp) cd $work_dir || exit 1 # # File copying # echo Copying package files... cat "$pkg_dir"/files | while read i; do if [ -z "$i" ] ; then continue fi if [[ "$i" =~ %[A-Z]*% ]] ; then current=$i continue fi case $current in %FILES%) ret=0 if [ -d "/$i" ]; then mkdir "$i" || ret=$? elif [ -f "/$i" ]; then cp -dp "/$i" "$i" || ret=$? else echo "/$i" is missing: this might result in a broken package fi if [ $ret -ne 0 ]; then echo Error: unable to create /$i exit 1 fi ;; esac done ret=$? if [ $ret -ne 0 ]; then rm -rf $work_dir exit 1 fi pkg_size=$(du -sb | awk '{print $1}') if [ -f "$pkg_dir/install" ] ; then cp "$pkg_dir/install" "$work_dir/.INSTALL" fi if [ -f $pkg_dir/changelog ] ; then cp "$pkg_dir/changelog" "$work_dir/.CHANGELOG" fi # # .PKGINFO stuff # echo Generating .PKGINFO metadata... echo "# Generated by $progname $progver" > .PKGINFO echo "# $(LC_ALL=C date)" >> .PKGINFO echo "#" >> .PKGINFO cat "$pkg_dir"/{desc,files,depends} | while read i; do if [[ -z "$i" ]]; then continue; fi if [[ "$i" =~ %[A-Z]*% ]] ; then current=$i continue fi case "$current" in # desc %NAME%) echo "pkgname = $i" >> .PKGINFO ;; %VERSION%) echo "pkgver = $i" >> .PKGINFO ;; %DESC%) echo "pkgdesc = $i" >> .PKGINFO ;; %URL%) echo "url = $i" >> .PKGINFO ;; %LICENSE%) echo "license = $i" >> .PKGINFO ;; %ARCH%) echo "arch = $i" >> .PKGINFO ;; %BUILDDATE%) echo "builddate = $(date -u "+%s")" >> .PKGINFO ;; %PACKAGER%) echo "packager = $pkg_pkger" >> .PKGINFO ;; %SIZE%) echo "size = $pkg_size" >> .PKGINFO ;; %GROUPS%) echo "group = $i" >> .PKGINFO ;; %REPLACES%) echo "replaces = $i" >> .PKGINFO ;; %FORCE%) echo "force = true" >> .PKGINFO ;; # files %BACKUP%) # strip the md5sum after the tab echo "backup = ${i%% *}" >> .PKGINFO ;; # depends %DEPENDS%) echo "depend = $i" >> .PKGINFO ;; %OPTDEPENDS%) echo "optdepend = $i" >> .PKGINFO ;; %CONFLICTS%) echo "conflict = $i" >> .PKGINFO ;; %PROVIDES%) echo "provides = $i" >> .PKGINFO ;; esac done # # Generate the package # echo Generating the package... ret=0 bsdtar -czf "$pkg_dest/$pkg_namver-$pkg_arch.tar.gz" $(ls -A) || ret=$? if [ $ret -ne 0 ]; then echo Error: unable to write package to $pkg_dest echo Maybe the disk is full or you do not have write access exit 1 fi rm -rf $work_dir echo Done exit 0 # vim: set ts=2 sw=2 noet:
On Fri, May 30, 2008 at 3:28 PM, Allan McRae <mcrae_allan@hotmail.com> wrote:
Here is my latest adjustment to the bacman script including all changes mentioned so far in the thread.
Great, that version looks alright to me.
Remaining issues are permissions: 1) Group information is lost 2) Directory permissions are always 755 3) Sometimes bails when user does not have permission to read file. I added a catch for this but it could probably be fixed with the above.
How could 3) be fixed? Anyway, I think the current script is really sufficient to replace repacman in the repo, so you can always propose a patch now to do that, and propose other patches later for the permissions (if you feel like it)
Il Friday 30 May 2008 15:28:18 Allan McRae ha scritto:
Here is my latest adjustment to the bacman script including all changes mentioned so far in the thread.
Remaining issues are permissions: 1) Group information is lost 2) Directory permissions are always 755 3) Sometimes bails when user does not have permission to read file. I added a catch for this but it could probably be fixed with the above.
Here might be a patch to fix 2) I don't know how to remove the warning about stripping the leading /, though. I was thinking that it would be nice to just create the tar archive with the files and then gzip it, instead of using the temporary directory which needs fakeroot -u in order to preserve ownerships. Maybe tomorrow. --- bacman 2008-05-31 01:20:12.000000000 +0200 +++ bacman.new 2008-05-31 01:35:06.000000000 +0200 @@ -117,10 +117,8 @@ case $current in %FILES%) ret=0 - if [ -d "/$i" ]; then - mkdir "$i" || ret=$? - elif [ -f "/$i" ]; then - cp -dp "/$i" "$i" || ret=$? + if [ -e "/$i" ]; then + bsdtar -cnf - "/$i" 2> /dev/null || ret=$? | bsdtar -xpf - else echo "/$i" is missing: this might result in a broken package fi Here's the complete script: #!/bin/bash # # bacman: recreate a package from a running system # This script rebuilds an already installed package using metadata # stored into the pacman database and system files # # (c) 2008 - locci <carlocci_at_gmail_dot_com> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # readonly progname="bacman" readonly progver="0.1.2" # # User Friendliness # function usage(){ echo "This program recreates a package using pacman's db and system files" echo "Usage: $progname <installed package name>" echo "Example: $progname kernel26" } if [ $# -ne 1 ] ; then usage exit 1 fi if [ "$1" = "--help" -o "$1" = "-h" ] ; then usage exit 0 fi if [ "$1" = "--version" -o "$1" = "-v" ]; then echo "$progname version $version" echo "Copyright (C) 2008 locci" exit 0 fi # # Setting environmental variables # if [ ! -r /etc/pacman.conf ]; then echo Error: unable to read /etc/pacman.conf exit 1 fi eval $(awk '/DBPath/ {print $1$2$3}' /etc/pacman.conf) pac_db="${DBPath:-/var/lib/pacman/}/local" if [ ! -r /etc/makepkg.conf ]; then echo Error: unable to read /etc/makepkg.conf exit 1 fi source "/etc/makepkg.conf" if [ -r ~/.makepkg.conf ]; then source ~/.makepkg.conf fi pkg_arch=${CARCH:-'unknown'} pkg_dest="${PKGDEST:-$PWD}" pkg_pkger=${PACKAGER:-'Unknown Packager'} pkg_name="$1" pkg_dir="$(echo $pac_db/$pkg_name-[0-9]*)" pkg_namver="${pkg_dir##*/}" # # Checks everything is in place # if [ ! -d "$pac_db" ] ; then echo Error: pacman database directory ${pac_db} not found exit 1 fi if [ ! -d "$pkg_dir" ] ; then echo Error: package ${pkg_name} not found in pacman database exit 1 fi # # Begin # echo Package: ${pkg_namver} work_dir=$(mktemp -d -p /tmp) cd $work_dir || exit 1 # # File copying # echo Copying package files... cat "$pkg_dir"/files | while read i; do if [ -z "$i" ] ; then continue fi if [[ "$i" =~ %[A-Z]*% ]] ; then current=$i continue fi case $current in %FILES%) ret=0 if [ -e "/$i" ]; then bsdtar -cnf - "/$i" 2> /dev/null || ret=$? | bsdtar -xpf - else echo "/$i" is missing: this might result in a broken package fi if [ $ret -ne 0 ]; then echo Error: unable to create /$i exit 1 fi ;; esac done ret=$? if [ $ret -ne 0 ]; then rm -rf $work_dir exit 1 fi pkg_size=$(du -sb | awk '{print $1}') if [ -f "$pkg_dir/install" ] ; then cp "$pkg_dir/install" "$work_dir/.INSTALL" fi if [ -f $pkg_dir/changelog ] ; then cp "$pkg_dir/changelog" "$work_dir/.CHANGELOG" fi # # .PKGINFO stuff # echo Generating .PKGINFO metadata... echo "# Generated by $progname $progver" > .PKGINFO echo "# $(LC_ALL=C date)" >> .PKGINFO echo "#" >> .PKGINFO cat "$pkg_dir"/{desc,files,depends} | while read i; do if [[ -z "$i" ]]; then continue; fi if [[ "$i" =~ %[A-Z]*% ]] ; then current=$i continue fi case "$current" in # desc %NAME%) echo "pkgname = $i" >> .PKGINFO ;; %VERSION%) echo "pkgver = $i" >> .PKGINFO ;; %DESC%) echo "pkgdesc = $i" >> .PKGINFO ;; %URL%) echo "url = $i" >> .PKGINFO ;; %LICENSE%) echo "license = $i" >> .PKGINFO ;; %ARCH%) echo "arch = $i" >> .PKGINFO ;; %BUILDDATE%) echo "builddate = $(date -u "+%s")" >> .PKGINFO ;; %PACKAGER%) echo "packager = $pkg_pkger" >> .PKGINFO ;; %SIZE%) echo "size = $pkg_size" >> .PKGINFO ;; %GROUPS%) echo "group = $i" >> .PKGINFO ;; %REPLACES%) echo "replaces = $i" >> .PKGINFO ;; %FORCE%) echo "force = true" >> .PKGINFO ;; # files %BACKUP%) # strip the md5sum after the tab echo "backup = ${i%% *}" >> .PKGINFO ;; # depends %DEPENDS%) echo "depend = $i" >> .PKGINFO ;; %OPTDEPENDS%) echo "optdepend = $i" >> .PKGINFO ;; %CONFLICTS%) echo "conflict = $i" >> .PKGINFO ;; %PROVIDES%) echo "provides = $i" >> .PKGINFO ;; esac done # # Generate the package # echo Generating the package... ret=0 bsdtar -czf "$pkg_dest/$pkg_namver-$pkg_arch.tar.gz" $(ls -A) || ret=$? if [ $ret -ne 0 ]; then echo Error: unable to write package to $pkg_dest echo Maybe the disk is full or you do not have write access exit 1 fi rm -rf $work_dir echo Done exit 0 # vim: set ts=2 sw=2 noet:
On 31/05/2008, at 8:27 AM, Carlo Bersani wrote:
pkg_size=$(du -sb | awk '{print $1}')
I suggest using "$(du -sk | awk '{print $1 * 1024}')" so that we don't have the same problem with portability as in makepkg[1]. [1] http://bugs.archlinux.org/task/10459 -- Sebastian Nowicki
On Sat, May 31, 2008 at 3:36 AM, Sebastian Nowicki <sebnow@gmail.com> wrote:
On 31/05/2008, at 8:27 AM, Carlo Bersani wrote:
pkg_size=$(du -sb | awk '{print $1}')
I suggest using "$(du -sk | awk '{print $1 * 1024}')" so that we don't have the same problem with portability as in makepkg[1].
Nice catch. -Dan
On Sat, May 31, 2008 at 3:03 PM, Dan McGee <dpmcgee@gmail.com> wrote:
On Sat, May 31, 2008 at 3:36 AM, Sebastian Nowicki <sebnow@gmail.com> wrote:
On 31/05/2008, at 8:27 AM, Carlo Bersani wrote:
pkg_size=$(du -sb | awk '{print $1}')
I suggest using "$(du -sk | awk '{print $1 * 1024}')" so that we don't have the same problem with portability as in makepkg[1].
Nice catch.
Yep right, I also noticed it previously, but at that moment the patch was not applied to makepkg yet and I was not 100% sure it would be : http://bbs.archlinux.org/viewtopic.php?pid=372994#p372994
Here is an inline version. Slightly changed from the version carlocci posted to fix a minor bug. Allan #!/bin/bash # # bacman: recreate a package from a running system # This script rebuilds an already installed package using metadata # stored into the pacman database and system files # # (c) 2008 - locci <carlocci_at_gmail_dot_com> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # readonly progname="bacman" readonly progver="0.1.2" # # User Friendliness # function usage(){ echo "This program recreates a package using pacman's db and system files" echo "Usage: $progname <installed package name>" echo "Example: $progname kernel26" } if [ $# -ne 1 ] ; then usage exit 1 fi if [ "$1" = "--help" -o "$1" = "-h" ] ; then usage exit 0 fi if [ "$1" = "--version" -o "$1" = "-v" ]; then echo "$progname version $version" echo "Copyright (C) 2008 locci" exit 0 fi # # Setting environmental variables # eval $(sed -nre 's:[[:space:]]*(DBPath)[[:space:]]*=[[:space:]]*([[:print:]]*):\1="\2":p' /etc/pacman.conf) pac_db="${DBPath:-/var/lib/pacman/}/local" eval $(sed -nre 's:[[:space:]]*(CacheDir)[[:space:]]*=[[:space:]]*([[:print:]]*):\1="\2":p' /etc/pacman.conf) pac_cache="${CacheDir:-/var/cache/pacman/pkg/}" pkg_name="$1" pkg_dir="$(echo $pac_db/$pkg_name-[0-9]*)" eval $(sed -nre 's:[[:space:]]*(CARCH)[[:space:]]*=[[:space:]]*([[:print:]]*):\1=\2:p' /etc/makepkg.conf) pkg_arch=${CARCH:-'unknown'} eval $(sed -nre 's:[[:space:]]*(PKGDEST)[[:space:]]*=[[:space:]]*([[:print:]]*):\1=\2:p' /etc/makepkg.conf) pkg_dest="${PKGDEST:-$PWD}" eval $(sed -nre 's:[[:space:]]*(PACKAGER)[[:space:]]*=[[:space:]]*([[:print:]]*):\1=\2:p' /etc/makepkg.conf) pkg_pkger=${PACKAGER:-'Unknown Packager'} pkg_namver="${pkg_dir##*/}" # # Checks everything is in place # if [ ! -d "$pac_db" ] ; then echo Error: pacman database directory ${pac_db} not found exit 1 fi if [ ! -d "$pac_cache" ] ; then echo Warning: pacman pkg cache directory ${pac_cache} not found unset pac_cache fi if [ ! -d "$pkg_dir" ] ; then echo Error: package ${pkg_name} not found in pacman database exit 1 fi if [ -n "$pac_cache" ] && [ -f "$pac_cache"/"$pkg_namver"*.tar.gz ] ; then echo Warning: the package ${pkg_name} already exists in your pacman cache # read -n 1 -p 'Do you want to fetch it instead? (y/N) ' # case $REPLY in # y|Y) # cp "$pac_cache"/"$pkg_namver"*.pkg.tar.gz "$pkg_dest" # exit 0 # ;; # *) echo "" # ;; # esac fi # # Begin # echo Package: ${pkg_namver} work_dir=$(mktemp -d -p /tmp) cd $work_dir || exit 1 # # File copying # echo Copying package files... cat "$pkg_dir"/files | while read i; do if [ -z "$i" ] ; then continue fi if [[ "$i" =~ %[A-Z]*% ]] ; then current=$i continue fi case $current in %FILES%) if [ -d "/$i" ]; then mkdir "$i" elif [ -f "/$i" ]; then install -D "/$i" "$i" else echo "/$i" is missing: this might result in a broken package fi ;; esac pkg_size=$(du -sb | awk '{print $1}') done echo Adding install commands and changelogs, if any... if [ -f "$pkg_dir/install" ] ; then cp "$pkg_dir/install" "$work_dir/.INSTALL" fi if [ -f $pkg_dir/changelog ] ; then cp "$pkg_dir/changelog" "$work_dir/.CHANGELOG" fi # # .PKGINFO stuff # echo echo Generating .PKGINFO metadata... echo "# Generated by $progname $progver" > .PKGINFO echo "# $(LC_ALL=C date)" >> .PKGINFO echo "#" >> .PKGINFO cat "$pkg_dir"/{desc,files,depends} | while read i; do if [[ -z "$i" ]]; then continue; fi if [[ "$i" =~ %[A-Z]*% ]] ; then current=$i continue fi case "$current" in # desc %NAME%) echo "pkgname = $i" >> .PKGINFO ;; %VERSION%) echo "pkgver = $i" >> .PKGINFO ;; %DESC%) echo "pkgdesc = $i" >> .PKGINFO ;; %URL%) echo "url = $i" >> .PKGINFO ;; %LICENSE%) echo "license = $i" >> .PKGINFO ;; %ARCH%) echo "arch = $i" >> .PKGINFO ;; %BUILDDATE%) echo "builddate = $(date -u "+%s")" >> .PKGINFO ;; %PACKAGER%) echo "packager = $pkg_pkger" >> .PKGINFO ;; %SIZE%) echo "size = $pkg_size" >> .PKGINFO ;; %GROUPS%) echo "group = $i" >> .PKGINFO ;; %REPLACES%) echo "replaces = $i" >> .PKGINFO ;; # files %BACKUP%) # strip the md5sum after the tab echo "backup = ${i%% *}" >> .PKGINFO ;; # depends %DEPENDS%) echo "depend = $i" >> .PKGINFO ;; %OPTDEPENDS%) echo "optdepend = $i" >> .PKGINFO ;; %CONFLICTS%) echo "conflict = $i" >> .PKGINFO ;; %PROVIDES%) echo "provides = $i" >> .PKGINFO ;; %FORCE%) echo "force = true" >> .PKGINFO ;; esac done # # Generate the package # echo echo Generating the package... ret=0 bsdtar -czf "$pkg_dest/$pkg_namver-$pkg_arch.tar.gz" $(ls -A) || ret=$? if [ $ret -ne 0 ]; then echo Error: Unable to write package to $pkg_dest echo Maybe the disk is full or you do not have write access exit 1 fi #rm -rf $work_dir exit 0 # vim: set ts=2 sw=2 noet:
It seems I was beaten to send it... Anyway, the only section I changed was this:
# # Setting environmental variables # eval $(sed -nre 's:[[:space:]]*(DBPath)[[:space:]]*=[[:space:]]*([[:print:]]*):\1="\2":p' /etc/pacman.conf) pac_db="${DBPath:-/var/lib/pacman/}/local" eval $(sed -nre 's:[[:space:]]*(CacheDir)[[:space:]]*=[[:space:]]*([[:print:]]*):\1="\2":p' /etc/pacman.conf) pac_cache="${CacheDir:-/var/cache/pacman/pkg/}" pkg_name="$1" pkg_dir="$(echo $pac_db/$pkg_name-[0-9]*)" eval $(sed -nre 's:[[:space:]]*(CARCH)[[:space:]]*=[[:space:]]*([[:print:]]*):\1=\2:p' /etc/makepkg.conf) pkg_arch=${CARCH:-'unknown'} eval $(sed -nre 's:[[:space:]]*(PKGDEST)[[:space:]]*=[[:space:]]*([[:print:]]*):\1=\2:p' /etc/makepkg.conf) pkg_dest="${PKGDEST:-$PWD}" eval $(sed -nre 's:[[:space:]]*(PACKAGER)[[:space:]]*=[[:space:]]*([[:print:]]*):\1=\2:p' /etc/makepkg.conf) pkg_pkger=${PACKAGER:-'Unknown Packager'} pkg_namver="${pkg_dir##*/}"
The mailing list doesn't like the length of those sed statements.... The eval statement appears to only work until the first comments so I changed it so that each variable needs to be read in separately. Also, those sed statements are monstrous... They do allow spaces in path names though. So the question is: Does pacman allow spaces in DBPath or CacheDir? If not we can simply those statements. It should not be needed for the reading of variables from makepkg.conf because they are bash variables and should be nicely quoted anyway. Allan
It seems I was beaten to send it...
Anyway, the only section I changed was this:
# # Setting environmental variables # eval $(sed -nre 's:[[:space:]]*(DBPath)[[:space:]]*=[[:space:]]*([[:print:]]*):\1="\2":p' /etc/pacman.conf) pac_db="${DBPath:-/var/lib/pacman/}/local" eval $(sed -nre 's:[[:space:]]*(CacheDir)[[:space:]]*=[[:space:]]*([[:print:]]*):\1="\2":p' /etc/pacman.conf) pac_cache="${CacheDir:-/var/cache/pacman/pkg/}" pkg_name="$1" pkg_dir="$(echo $pac_db/$pkg_name-[0-9]*)" eval $(sed -nre 's:[[:space:]]*(CARCH)[[:space:]]*=[[:space:]]*([[:print:]]*):\1=\2:p' /etc/makepkg.conf) pkg_arch=${CARCH:-'unknown'} eval $(sed -nre 's:[[:space:]]*(PKGDEST)[[:space:]]*=[[:space:]]*([[:print:]]*):\1=\2:p' /etc/makepkg.conf) pkg_dest="${PKGDEST:-$PWD}" eval $(sed -nre 's:[[:space:]]*(PACKAGER)[[:space:]]*=[[:space:]]*([[:print:]]*):\1=\2:p' /etc/makepkg.conf) pkg_pkger=${PACKAGER:-'Unknown Packager'} pkg_namver="${pkg_dir##*/}"
The mailing list doesn't like the length of those sed statements.... It is gmail, not the mailing list. git-send-email seems to handle long
On Thu, May 29, 2008 at 7:19 PM, Allan McRae <mcrae_allan@hotmail.com> wrote: lines, for instance.
The eval statement appears to only work until the first comments so I changed it so that each variable needs to be read in separately.
Also, those sed statements are monstrous... They do allow spaces in path names though. So the question is: Does pacman allow spaces in DBPath or CacheDir? If not we can simply those statements. It should not be needed for the reading of variables from makepkg.conf because they are bash variables and should be nicely quoted anyway.
We should just be able to source makepkg.conf, no need to sed it to death. Be sure we source ~/.makepkg.conf as well though if this script can be run as a user. Just look to makepkg to see the canonical way to do all this. Man I wish there was a better way to get the pacman.conf stuff in. I'll take a further look at everything else later, but I don't have the time tonight. Hopefully some others can offer some feedback and this can get plunked in contrib/. -Dan
On Thu, May 29, 2008 at 7:25 PM, Dan McGee <dpmcgee@gmail.com> wrote:
It seems I was beaten to send it...
Anyway, the only section I changed was this:
# # Setting environmental variables # eval $(sed -nre 's:[[:space:]]*(DBPath)[[:space:]]*=[[:space:]]*([[:print:]]*):\1="\2":p' /etc/pacman.conf) pac_db="${DBPath:-/var/lib/pacman/}/local" eval $(sed -nre 's:[[:space:]]*(CacheDir)[[:space:]]*=[[:space:]]*([[:print:]]*):\1="\2":p' /etc/pacman.conf) pac_cache="${CacheDir:-/var/cache/pacman/pkg/}" pkg_name="$1" pkg_dir="$(echo $pac_db/$pkg_name-[0-9]*)" eval $(sed -nre 's:[[:space:]]*(CARCH)[[:space:]]*=[[:space:]]*([[:print:]]*):\1=\2:p' /etc/makepkg.conf) pkg_arch=${CARCH:-'unknown'} eval $(sed -nre 's:[[:space:]]*(PKGDEST)[[:space:]]*=[[:space:]]*([[:print:]]*):\1=\2:p' /etc/makepkg.conf) pkg_dest="${PKGDEST:-$PWD}" eval $(sed -nre 's:[[:space:]]*(PACKAGER)[[:space:]]*=[[:space:]]*([[:print:]]*):\1=\2:p' /etc/makepkg.conf) pkg_pkger=${PACKAGER:-'Unknown Packager'} pkg_namver="${pkg_dir##*/}"
The mailing list doesn't like the length of those sed statements.... It is gmail, not the mailing list. git-send-email seems to handle long
On Thu, May 29, 2008 at 7:19 PM, Allan McRae <mcrae_allan@hotmail.com> wrote: lines, for instance.
The eval statement appears to only work until the first comments so I changed it so that each variable needs to be read in separately.
Also, those sed statements are monstrous... They do allow spaces in path names though. So the question is: Does pacman allow spaces in DBPath or CacheDir? If not we can simply those statements. It should not be needed for the reading of variables from makepkg.conf because they are bash variables and should be nicely quoted anyway.
We should just be able to source makepkg.conf, no need to sed it to death. Be sure we source ~/.makepkg.conf as well though if this script can be run as a user. Just look to makepkg to see the canonical way to do all this.
Man I wish there was a better way to get the pacman.conf stuff in.
I'll take a further look at everything else later, but I don't have the time tonight. Hopefully some others can offer some feedback and this can get plunked in contrib/.
FYI He's sed-ing pacman.conf, not makepkg.conf. I thought it was neat, but crazy-complex
Dan McGee wrote:
The eval statement appears to only work until the first comments so I changed it so that each variable needs to be read in separately.
Also, those sed statements are monstrous... They do allow spaces in path names though. So the question is: Does pacman allow spaces in DBPath or CacheDir? If not we can simply those statements. It should not be needed for the reading of variables from makepkg.conf because they are bash variables and should be nicely quoted anyway.
We should just be able to source makepkg.conf, no need to sed it to death. Be sure we source ~/.makepkg.conf as well though if this script can be run as a user. Just look to makepkg to see the canonical way to do all this.
Nice catch. I had forgotten about the local user version.
Man I wish there was a better way to get the pacman.conf stuff in.
Well, if both DBPath and CacheDir _can not_ have spaces in them, this can be simplified to (from earlier versions of the script): eval $(awk '/CacheDir/ {print $1$2$3}' /etc/pacman.conf) That is far less ugly but won't handle spaces in those paths. Now the question is, does pacman actually allow spaces in those path names? I'm not familiar with that part of the pacman code.
On 2008-05-20, Allan McRae wrote:
Well, if both DBPath and CacheDir _can not_ have spaces in them, this can be simplified to (from earlier versions of the script): eval $(awk '/CacheDir/ {print $1$2$3}' /etc/pacman.conf)
FWIW this will do the same and takes care of a leading #. eval $(sed -n 's:^#:: ;/CacheDir/ s: *::gp' /etc/pacman.conf) --markc
On Fri, May 30, 2008 at 2:10 AM, Allan McRae <mcrae_allan@hotmail.com> wrote:
# # Setting environmental variables # eval $(sed -nre 's:[[:space:]]*(DBPath)[[:space:]]*=[[:space:]]*([[:print:]]*):\1="\2":p' /etc/pacman.conf) pac_db="${DBPath:-/var/lib/pacman/}/local" eval $(sed -nre 's:[[:space:]]*(CacheDir)[[:space:]]*=[[:space:]]*([[:print:]]*):\1="\2":p' /etc/pacman.conf) pac_cache="${CacheDir:-/var/cache/pacman/pkg/}" pkg_name="$1" pkg_dir="$(echo $pac_db/$pkg_name-[0-9]*)" eval $(sed -nre 's:[[:space:]]*(CARCH)[[:space:]]*=[[:space:]]*([[:print:]]*):\1=\2:p' /etc/makepkg.conf) pkg_arch=${CARCH:-'unknown'} eval $(sed -nre 's:[[:space:]]*(PKGDEST)[[:space:]]*=[[:space:]]*([[:print:]]*):\1=\2:p' /etc/makepkg.conf) pkg_dest="${PKGDEST:-$PWD}" eval $(sed -nre 's:[[:space:]]*(PACKAGER)[[:space:]]*=[[:space:]]*([[:print:]]*):\1=\2:p' /etc/makepkg.conf) pkg_pkger=${PACKAGER:-'Unknown Packager'} pkg_namver="${pkg_dir##*/}"
I don't like this complexity either, better revert to your awk way. I would suggest to not worry about spaces unless you find a clever and simple way to handle them.
if [ -n "$pac_cache" ] && [ -f "$pac_cache"/"$pkg_namver"*.tar.gz ] ; then echo Warning: the package ${pkg_name} already exists in your pacman cache # read -n 1 -p 'Do you want to fetch it instead? (y/N) ' # case $REPLY in # y|Y) # cp "$pac_cache"/"$pkg_namver"*.pkg.tar.gz "$pkg_dest" # exit 0 # ;; # *) echo "" # ;; # esac fi
You commented out this part on purpose? I don't find it useful either, just remove it :)
# # File copying # echo Copying package files...
cat "$pkg_dir"/files | while read i; do
<snip>
pkg_size=$(du -sb | awk '{print $1}') done
Not only that var is not available outside the loop, it does not make any sense to put it inside anyway.
# desc %NAME%) echo "pkgname = $i" >> .PKGINFO ;; %VERSION%) echo "pkgver = $i" >> .PKGINFO ;; %DESC%) echo "pkgdesc = $i" >> .PKGINFO ;; %URL%) echo "url = $i" >> .PKGINFO ;; %LICENSE%) echo "license = $i" >> .PKGINFO ;; %ARCH%) echo "arch = $i" >> .PKGINFO ;; %BUILDDATE%) echo "builddate = $(date -u "+%s")" >> .PKGINFO ;; %PACKAGER%) echo "packager = $pkg_pkger" >> .PKGINFO ;; %SIZE%) echo "size = $pkg_size" >> .PKGINFO ;; %GROUPS%) echo "group = $i" >> .PKGINFO ;; %REPLACES%) echo "replaces = $i" >> .PKGINFO ;;
force belongs here, in desc section, just after replaces (and require indentation fix :)) :
%FORCE%) echo "force = true" >> .PKGINFO ;;
#rm -rf $work_dir
I thought you wanted to keep that.
participants (8)
-
Aaron Griffin
-
Allan McRae
-
Carlo Bersani
-
carlocci
-
Dan McGee
-
Mark Constable
-
Sebastian Nowicki
-
Xavier