[pacman-dev] [PATCH] repo-add: bash implementation of realpath
Replaced readlink -f / realpath with a more portable bash implementation. Signed-off-by: Yun Zheng Hu <yunzheng.hu@gmail.com> --- scripts/repo-add.sh.in | 37 ++++++++++++++++++++++++------------- 1 files changed, 24 insertions(+), 13 deletions(-) diff --git a/scripts/repo-add.sh.in b/scripts/repo-add.sh.in index c89e2a5..f266719 100644 --- a/scripts/repo-add.sh.in +++ b/scripts/repo-add.sh.in @@ -107,7 +107,7 @@ write_list_entry() { db_write_delta() { # blank out all variables and set deltafile to absolute path - local deltafile=$($realpath "$1") + local deltafile=$(realpath "$1") local filename=$(basename "$deltafile") local deltavars pkgname fromver tover arch csize md5sum @@ -138,7 +138,7 @@ db_write_delta() db_write_entry() { # blank out all variables and set pkgfile to an absolute path - local pkgfile=$($realpath "$1") + local pkgfile=$(realpath "$1") local pkgname pkgver pkgdesc url builddate packager csize size \ group depend backup license replaces provides conflict force \ _groups _depends _backups _licenses _replaces _provides _conflicts \ @@ -267,6 +267,27 @@ db_remove_entry() { popd 2>&1 >/dev/null } # end db_remove_entry +# bash implementation of realpath / readlink -f +# arg1 - filename +realpath() +{ + fname=${1%/} # strips trailing '/' + while [ -L "$fname" ]; do + oldfname="$fname" + fname="$(command ls -l $fname)" + fname="${fname#*\> }" + if [ "$fname" = . ] ; then + fname="$(dirname $oldfname)" + elif echo $fname | grep -vq '^/' - ; then + fname="$(dirname $oldfname)/$fname" + fi + done + pushd $(dirname $fname) > /dev/null + fname=$(pwd -P)/$(basename $fname) + popd > /dev/null + echo $fname +} + # PROGRAM START # determine whether we have gettext; make it a no-op if we do not @@ -294,16 +315,6 @@ if [ $# -lt 2 ]; then exit 1 fi -# check for and store the name of a realpath-like program -if [ $(type -t realpath) ]; then - realpath='realpath' -elif [ $(type -t readlink) ]; then - realpath='readlink -f' -else - error "$(gettext "Either realpath or readlink are required by repo-add.")" - exit 1 # $E_MISSING_PROGRAM -fi - # main routine gstmpdir=$(mktemp -d /tmp/repo-tools.XXXXXXXXXX) || (\ error "$(gettext "Cannot create temp directory for database building.")"; \ @@ -326,7 +337,7 @@ for arg in "$@"; do QUIET=1 elif [ -z "$REPO_DB_FILE" ]; then # store absolute path to repo DB - REPO_DB_FILE=$($realpath "$arg") + REPO_DB_FILE=$(realpath "$arg") if [ -f "$REPO_DB_FILE" ]; then if ! test_repo_db_file $cmd; then error "$(gettext "Repository file '%s' is not a proper pacman database.")" "$REPO_DB_FILE" -- 1.6.1.2
On Sun, Feb 15, 2009 at 9:21 AM, Yun Zheng Hu <yunzheng.hu@gmail.com> wrote:
Replaced readlink -f / realpath with a more portable bash implementation.
Signed-off-by: Yun Zheng Hu <yunzheng.hu@gmail.com> ---
Looks good, but: $ git am -3 -s < /tmp/repo-add-realpath.patch Applying: repo-add: bash implementation of realpath error: patch failed: scripts/repo-add.sh.in:326 error: scripts/repo-add.sh.in: patch does not apply Using index info to reconstruct a base tree... error: patch failed: scripts/repo-add.sh.in:326 error: scripts/repo-add.sh.in: patch does not apply Did you hand edit your patch? It does not apply to blobs recorded in its index. Cannot fall back to three-way merge. Patch failed at 0001. When you have resolved this problem run "git am -3 --resolved". If you would prefer to skip this patch, instead run "git am -3 --skip". To restore the original branch and stop patching run "git am -3 --abort". Can you resubmit? I'm not sure if you actually hand-edited this, causing the sha1sum values to be off, but I'm curious why I've had two patches fail on me tonight when applying them. -Dan
Dan McGee wrote:
On Sun, Feb 15, 2009 at 9:21 AM, Yun Zheng Hu <yunzheng.hu@gmail.com> wrote:
Replaced readlink -f / realpath with a more portable bash implementation.
Signed-off-by: Yun Zheng Hu <yunzheng.hu@gmail.com> ---
Looks good, but:
$ git am -3 -s < /tmp/repo-add-realpath.patch Applying: repo-add: bash implementation of realpath error: patch failed: scripts/repo-add.sh.in:326 error: scripts/repo-add.sh.in: patch does not apply Using index info to reconstruct a base tree... error: patch failed: scripts/repo-add.sh.in:326 error: scripts/repo-add.sh.in: patch does not apply Did you hand edit your patch? It does not apply to blobs recorded in its index. Cannot fall back to three-way merge. Patch failed at 0001. When you have resolved this problem run "git am -3 --resolved". If you would prefer to skip this patch, instead run "git am -3 --skip". To restore the original branch and stop patching run "git am -3 --abort".
Can you resubmit? I'm not sure if you actually hand-edited this, causing the sha1sum values to be off, but I'm curious why I've had two patches fail on me tonight when applying them.
-Dan
Did anyone provide differences in speed when using the bash "realpath" to the actual binary one? My guess is that the speed difference will be minimal, even when regenerating an entire repo db, but it would pay to check. Allan
On Sun, Feb 15, 2009 at 8:44 PM, Allan McRae <allan@archlinux.org> wrote:
Dan McGee wrote:
On Sun, Feb 15, 2009 at 9:21 AM, Yun Zheng Hu <yunzheng.hu@gmail.com> wrote:
Replaced readlink -f / realpath with a more portable bash implementation.
Signed-off-by: Yun Zheng Hu <yunzheng.hu@gmail.com> ---
Looks good, but:
$ git am -3 -s < /tmp/repo-add-realpath.patch Applying: repo-add: bash implementation of realpath error: patch failed: scripts/repo-add.sh.in:326 error: scripts/repo-add.sh.in: patch does not apply Using index info to reconstruct a base tree... error: patch failed: scripts/repo-add.sh.in:326 error: scripts/repo-add.sh.in: patch does not apply Did you hand edit your patch? It does not apply to blobs recorded in its index. Cannot fall back to three-way merge. Patch failed at 0001. When you have resolved this problem run "git am -3 --resolved". If you would prefer to skip this patch, instead run "git am -3 --skip". To restore the original branch and stop patching run "git am -3 --abort".
Can you resubmit? I'm not sure if you actually hand-edited this, causing the sha1sum values to be off, but I'm curious why I've had two patches fail on me tonight when applying them.
-Dan
Did anyone provide differences in speed when using the bash "realpath" to the actual binary one? My guess is that the speed difference will be minimal, even when regenerating an entire repo db, but it would pay to check.
I agree, especially after the speed differences Xavier pointed out with my other repo-add patch. -Dan
On Mon, Feb 16, 2009 at 4:20 AM, Dan McGee <dpmcgee@gmail.com> wrote:
On Sun, Feb 15, 2009 at 8:44 PM, Allan McRae <allan@archlinux.org> wrote:
Did anyone provide differences in speed when using the bash "realpath" to the actual binary one? My guess is that the speed difference will be minimal, even when regenerating an entire repo db, but it would pay to check.
I agree, especially after the speed differences Xavier pointed out with my other repo-add patch.
bash realpath real 0m3.138s user 0m0.887s sys 0m1.710s readlink -f real 0m0.734s user 0m0.210s sys 0m0.507s Before moving forward, I have a question : is there any good and portable way to convert between absolute and relative paths? I don't see any reason for doing any symlinks resolution anywhere. The only thing we need is to convert a given path (which can be either absolute or relative) to an absolute path. We need this because we are changing directories, and these paths have to stay valid so have to be absolute. Another alternative for getting rid of realpath/readlink is to avoid changing directories in the first place. This might also be possible but probably requires more work.
On 16/02/2009, at 6:25 PM, Xavier wrote:
Before moving forward, I have a question : is there any good and portable way to convert between absolute and relative paths? I don't see any reason for doing any symlinks resolution anywhere. The only thing we need is to convert a given path (which can be either absolute or relative) to an absolute path. We need this because we are changing directories, and these paths have to stay valid so have to be absolute.
After a bit of Googling I haven't been able to find a solution. On the contrary, many posts indicate that there is no cross-platform way - at least not without introducing huge dependencies (python/ruby/etc). It's weird considering that there's a standard C function[1] which does exactly this. A semi-ugly solution would be to provide an executable which simply calls this function, as part of the pacman package. However, if the speed difference is not that important, the bash implementation is a nicer solution. [1]: http://www.opengroup.org/onlinepubs/000095399/functions/realpath.html
On Mon, Feb 16, 2009 at 10:50 AM, Sebastian Nowicki <sebnow@gmail.com> wrote:
On 16/02/2009, at 6:25 PM, Xavier wrote:
Before moving forward, I have a question : is there any good and portable way to convert between absolute and relative paths? I don't see any reason for doing any symlinks resolution anywhere. The only thing we need is to convert a given path (which can be either absolute or relative) to an absolute path. We need this because we are changing directories, and these paths have to stay valid so have to be absolute.
After a bit of Googling I haven't been able to find a solution. On the contrary, many posts indicate that there is no cross-platform way - at least not without introducing huge dependencies (python/ruby/etc). It's weird considering that there's a standard C function[1] which does exactly this. A semi-ugly solution would be to provide an executable which simply calls this function, as part of the pacman package. However, if the speed difference is not that important, the bash implementation is a nicer solution.
[1]: http://www.opengroup.org/onlinepubs/000095399/functions/realpath.html
That's so crazy and disappointing.. But well, since we are considering to implement our own thing in bash, maybe we could just go with a simpler bash function that just builds the absolute path? I saw several implementations in bash using a combination of dirname, basename, cd and pwd. Hopefully these 4 tools are portable. Otherwise dirname and basename can be reimplemented as well without too much complexity.
participants (5)
-
Allan McRae
-
Dan McGee
-
Sebastian Nowicki
-
Xavier
-
Yun Zheng Hu