[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
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
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 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
On Fri, May 30, 2008 at 3:28 PM, Allan McRae
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
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
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
On Sat, May 31, 2008 at 3:36 AM, Sebastian Nowicki
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
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
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
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
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
# # 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