[flashrom] [PATCH 2/2] Improve getrevision.sh.

David Hendricks dhendrix at google.com
Wed Aug 7 05:09:19 CEST 2013


Overall this is great! I definitely think it's easier to read, test, and
maintain than the Makefile approach. But I suppose we'll find out how
others feel...

On Tue, Aug 6, 2013 at 6:51 PM, Stefan Tauner <
stefan.tauner at student.tuwien.ac.at> wrote:

>  - remove bashism
>  - simplify some git-related code
>  - there is only one sane time format.
>  - vastly improve git_url() to print the correct remote url and
>    "nearest" branch
>  - add "-dirty" to local revisions if there are uncommitted changes
>  - indicate in local revisions how many git-only commits were done
>    since branching from upstream svn
>  - fix svn_revision() fallback to svn info and remove git-svn
>  - print leading r in script instead of hardcode it in the makefile;
>    no more "0.9.7-runknown"
>
> Signed-off-by: Stefan Tauner <stefan.tauner at student.tuwien.ac.at>
> ---
>  Makefile            |   2 +-
>  util/getrevision.sh | 156
> +++++++++++++++++++++++++++++-----------------------
>  2 files changed, 89 insertions(+), 69 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index da0d0da..e1a4474 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -329,7 +329,7 @@ CLI_OBJS = cli_classic.o cli_output.o print.o
>  SVNVERSION := $(shell ./util/getrevision.sh -u)
>
>  RELEASE := 0.9.6.1
> -VERSION := $(RELEASE)-r$(SVNVERSION)
> +VERSION := $(RELEASE)-$(SVNVERSION)
>  RELEASENAME ?= $(VERSION)
>
>  SVNDEF := -D'FLASHROM_VERSION="$(VERSION)"'
> diff --git a/util/getrevision.sh b/util/getrevision.sh
> index 678d66b..95a57fe 100755
> --- a/util/getrevision.sh
> +++ b/util/getrevision.sh
> @@ -5,6 +5,7 @@
>  # Copyright (C) 2005 coresystems GmbH <stepan at coresystems.de>
>  # Copyright (C) 2009,2010 Carl-Daniel Hailfinger
>  # Copyright (C) 2010 Chromium OS Authors
> +# Copyright (C) 2013 Stefan Tauner
>  #
>  # 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
> @@ -23,18 +24,17 @@
>
>  EXIT_SUCCESS=0
>  EXIT_FAILURE=1
> +date_format="+%Y-%m-%dT%H:%M:%S%z" # There is only one valid timeformat
> FFS! ISO 8601
>
>  svn_revision() {
>         LC_ALL=C svnversion -cn . 2>/dev/null | \
> -               sed -e "s/.*://" -e "s/\([0-9]*\).*/\1/" | \
> -               grep "[0-9]" ||
> +               sed -e "s/.*://" -e "s/\([0-9]*\).*/r\1/" | \
> +               grep "r[0-9]" ||
>         LC_ALL=C svn info . 2>/dev/null | \
> -               awk '/^Revision:/ {print $$2 }' | \
> -               grep "[0-9]" ||
> -       LC_ALL=C git svn info . 2>/dev/null | \
> -               awk '/^Revision:/ {print $$2 }' | \
> -               grep "[0-9]" ||
> -       echo ''
> +               grep "Last Changed Rev:" | \
> +               sed -e "s/^Last Changed Rev: *//" -e "s/\([0-9]*\).*/r\1/"
> | \
> +               grep "r[0-9]" ||
> +       echo "unknown"
>  }
>
>  svn_url() {
> @@ -45,74 +45,81 @@ svn_url() {
>               )
>  }
>
> +svn_has_local_changes() {
> +       svn status | egrep '^ *[ADMR] *' > /dev/null
> +}
> +
>  svn_timestamp() {
> -       local date_format="+%Y-%m-%d %H:%M:%S"
>         local timestamp
>
> -       # are there local changes in the client?
> -       if svn status | egrep '^ *[ADMR] *' > /dev/null ; then
> -               timestamp=$(date "${date_format} +")
> +       if svn_has_local_changes ; then
> +               timestamp=$(date "${date_format}")
>         else
>                 # No local changes, get date of the last log record.
>                 local last_commit_date=$(svn info | grep '^Last Changed
> Date:' | \
>                                          awk '{print $4" "$5" "$6}')
> -               timestamp=$(date --utc --date "${last_commit_date}" \
> -                               "${date_format} UTC")
> +               timestamp=$(date -d "${last_commit_date}" "${date_format}")
>         fi
>
>         echo "${timestamp}"
>  }
>
> -git_revision() {
> -       echo $(git log --oneline | head -1 | awk '{print $1}')
> -}
> -
> -# Retrieve svn revision using git log data (for git mirrors)
> +# Retrieve svn revision using git log data (for git-svn mirrors)
>  gitsvn_revision() {
>         local r
>
> -       git log|
> -               grep git-svn-id|
> -               sed
> 's/.*git-svn-id:[[:blank:]]*\([^@]\+\)@[0-9]\+[[:blank:]]\+\([^[:blank:]]\+\)/\1
> \2/'|
> -               sort|
> -               uniq|
> -               read url uuid
> -
> -       r=$(git log --grep="git-svn-id.*$uuid"| grep git-svn-id | \
> -               sed 's/.*@//;s/[[:blank:]].*//'| \
> -               sort -n | \
> -               tail -1)
> +       # If this is a "native" git-svn clone we could use git svn log
> like so
> +       # if [ -e .git/svn/.metadata ]; then
> +       #       r=$(git svn log --oneline -1 | sed
> 's/^r//;s/[[:blank:]].*//')
> +       # else
> +               r=$(git log --grep git-svn-id -1 | \
> +                       grep git-svn-id | \
> +                       sed 's/.*@/r/;s/[[:blank:]].*//')
> +       # fi
>
>         echo "${r}"
>  }
>
> +git_has_local_changes() {
> +       git update-index -q --refresh
> +       ! git diff-index --quiet HEAD --
> +}
> +
>  git_timestamp() {
> -       local date_format="+%b %d %Y %H:%M:%S"
>         local timestamp
>
> -       # are there local changes in the client?
> -       if git status | \
> -          egrep '^# Change(s to be committed|d but not updated):$' >
> /dev/null
> -       then
> -               timestamp=$(date "${date_format} +")
> +       # are there local changes?
> +       if git_has_local_changes ; then
> +               timestamp=$(date "${date_format}")
>         else
> -               # No local changes, get date of the last log record.
> -               local last_commit_date=$(git log | head -3 | grep '^Date:'
> | \
> -                                        awk '{print $3" "$4" "$6" "$5"
> "$7}')
> -               timestamp=$(date --utc --date "${last_commit_date}" \
> -                           "${date_format} UTC")
> +               # No local changes, get date of the last commit
> +               timestamp=$(date -d "$(git log --pretty=format:"%cD" -1)"
> "${date_format}")
>         fi
>
>         echo "${timestamp}"
>  }
>
>  git_url() {
> -       # Only the first line of `git remote' is considered.
> -       echo $(LC_ALL=C git remote show origin 2>/dev/null |
> -              grep 'Fetch URL:' |
> -              sed 's/.*URL:[[:blank:]]*//' |
> -              grep ^.
> -             )
> +       # get all remote branches containing the last commit
> +       branches=$(git branch -r --contains HEAD | cut -c 3-)
> +       if [ -z "$branches" ] ; then
> +               echo "No remote branch contains current HEAD">&2
> +               return
> +       fi
> +
> +       # find "nearest" branch
> +       local diff=9000
> +       local target=
> +       for branch in $branches ; do
> +               curdiff=$(git rev-list --count HEAD..$branch)
> +               if [ $curdiff -ge $diff ] ; then
> +                       continue
> +               fi
> +               diff=$curdiff
> +               target=$branch
> +       done
> +
> +       echo "$(git ls-remote --exit-code --get-url ${target%/*})
> ${target#*/}"
>  }
>

I am seeing a lot of errors when trying this. The version in the previous
patch worked, though it kept the http:// prefix which is kind of
superfluous.

Try cloning http://git.chromium.org/chromiumos/third_party/flashrom.git .

$ sh getrevision.sh -U
fatal: ambiguous argument 'HEAD..->': unknown revision or path not in the
working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
getrevision.sh: line 115: [: -ge: unary operator expected
getrevision.sh: line 115: [: 0: unary operator expected
http://git.chromium.org/chromiumos/third_party/flashrom.git master

What about something like:
git ls-remote --exit-code --get-url | sed 's/.*\/\///'

That looks simpler and works better, at least in my testing...



>
>  scm_url() {
> @@ -142,16 +149,26 @@ timestamp() {
>         echo ${t}
>  }
>
> -# Retrieve local SCM revision info. This is useful if we're working in
> -# a even different SCM than upstream.
> +
> +# Retrieve local SCM revision info. This is useful if we're working in a
> different SCM than upstream and/or
> +# have local changes.
>  #
> -# If local copy is svn, then there is nothing to do here.
> -# If local copy is git, then retrieve useful git revision info
>  local_revision() {
>         local r
>
> -       if [ -d ".git" ] ; then
> -               r=$(git_revision)
> +       if [ -d ".svn" ] ; then
> +               r=$(svn_has_local_changes && echo "-dirty")
> +       elif [ -d ".git" ] ; then
> +               r=$(git rev-parse --short HEAD)
> +
> +               local svn_base=$(git log --grep git-svn-id -1
> --format='%h')
> +               if [ "$svn_base" != "" ] ; then
> +                       r="$r-$(git rev-list --count $svn_base..HEAD)"
> +               fi
> +
> +               if git_has_local_changes ; then
> +                       r="$r-dirty"
> +               fi
>         fi
>
>         echo ${r}
> @@ -168,6 +185,8 @@ upstream_revision() {
>                 r=$(svn_revision)
>         elif [ -d ".git" ] ; then
>                 r=$(gitsvn_revision)
> +       else
> +               r="unknown"
>         fi
>
>         echo "${r}"
> @@ -180,48 +199,49 @@ show_help() {
>  Options
>      -h or --help
>          Display this message.
> +    -l or --local
> +        local revision (if different from upstream) and an indicator for
> uncommitted changes
>      -u or --upstream
>          upstream flashrom revision
> -    -l or --local
> -        local revision (if different from upstream)
> -    -t or --timestamp
> -        timestamp of most recent modification
>      -U or --url
>          url associated with local copy of flashrom
> +    -t or --timestamp
> +        timestamp of most recent modification
>         "
>         return
>  }
>
> -if [ ! -n "${1}" ]
> -then
> +if [ -z "${1}" ] ; then
>         show_help;
>         echo "No options specified";
> -       exit ${EXIT_SUCCESS}
> +       exit ${EXIT_FAILURE}
>  fi
>
>  # The is the main loop
> -while [[ ${1} = -* ]];
> +while [ $# -gt 0 ];
>  do
>         case ${1} in
>         -h|--help)
>                 show_help;
>                 shift;;
> -       -u|--upstream)
> -               echo "$(upstream_revision)";
> -               shift;;
>         -l|--local)
>                 echo "$(local_revision)";
>                 shift;;
> -       -t|--timestamp)
> -               echo "$(timestamp)";
> +       -u|--upstream)
> +               echo "$(upstream_revision)";
>                 shift;;
>         -U|--url)
>                 echo "$(scm_url)";
>                 shift;;
> -       *)
> +       -t|--timestamp)
> +               echo "$(timestamp)";
> +               shift;;
> +       -*)
>                 show_help;
>                 echo "invalid option: ${1}"
> -               exit ${EXIT_FAILURE}
> +               exit ${EXIT_FAILURE};;
> +       *)
> +               shift;; # ignore arguments not starting with -
>         esac;
>  done
>
> --
> Kind regards, Stefan Tauner
>
>
> _______________________________________________
> flashrom mailing list
> flashrom at flashrom.org
> http://www.flashrom.org/mailman/listinfo/flashrom
>



-- 
David Hendricks (dhendrix)
Systems Software Engineer, Google Inc.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.flashrom.org/pipermail/flashrom/attachments/20130806/b2f45112/attachment.html>


More information about the flashrom mailing list