I had some time to take another stab at this, make the shell script
standalone (easier testing), and break the changes down much further. Much
of it recycles bits and pieces which Vadim and Carl-Daniel wrote (Including
the workaround from the blog post) and chops it into more digestible pieces.

I think this approach will be more maintainable and testable in the future
than the huge series of shell commands in-lined in the Makefile. This also
gives us the flexibility to punt disruptive changes until after the 0.9.3
release, rather than making all the changes at once.

The first patch only adds the script to util/ and is completely benign. The
second patch non-disruptively changes the Makefile to utilize the script for
SVNVERSION. The third patch disruptively changes the "flashrom --version"
output to add the extra information. I expect we'll spend a while longer
discussing the third one :-)

Here are the results after applying all three patches:
dhend...@thegates:flashrom$ ./util/getrevision.sh -h
Usage:
        ./util/getrevision.sh <option>

Options
    -h or --help
        Display this message.
    -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

*Test setup #1*: SVN repo with no local modifications
Since this is an SVN repo in this case, there is no local revision to take
into account.
dhend...@thegates:flashrom-head$ ./util/getrevision.sh -u -l -t -U
1155

2010-09-07 18:14:53 UTC
svn://coreboot.org/flashrom/trunk

dhend...@thegates:flashrom-head$ sudo ./flashrom --version
flashrom v0.9.2-r1155 from svn://coreboot.org/flashrom/trunk, no local
revision, timestamp 2010-09-07 15:03:38 +,  on Linux 2.6.32-14-generic
(x86_64), built with libpci 3.0.0, GCC 4.4.3, little endian
flashrom is free software, get the source code at http://www.flashrom.org

*Test setup #2*: SVN repo with local modifications
Since this is an SVN repo in this case, there is no local revision to take
into account. However, I have changed files in this case, so the timestamp
has been modified.

dhend...@thegates:flashrom-gitfriendly$ ./util/getrevision.sh -u -l -t -U
1155

2010-09-07 14:48:24 +
svn://coreboot.org/flashrom/trunk

flashrom v0.9.2-r1155 from svn://coreboot.org/flashrom/trunk, no local
revision, timestamp 2010-09-07 15:03:39 +,  on Linux 2.6.32-14-generic
(x86_64), built with libpci 3.0.0, GCC 4.4.3, little endian
flashrom is free software, get the source code at http://www.flashrom.org

*Test setup #3*: Git repo with no local modifications
Since this is a git repo, we will use the hash (668198a) as the local
revision.

dhend...@thegates:flashrom-git-nomods$ ./util/getrevision.sh -u -l -t -U
1130
668198a
Sep 07 2010 04:34:27 UTC
http://src.chromium.org/git/flashrom.git

dhend...@thegates:flashrom$ sudo ./flashrom --version
flashrom v0.9.2-r1130 from http://src.chromium.org/git/flashrom.git, local
revision 668198a, timestamp Sep 07 2010 15:21:00 +,  on Linux
2.6.32-14-generic (x86_64), built with libpci 3.0.0, GCC 4.4.3, little
endian
flashrom is free software, get the source code at http://www.flashrom.org

*Test setup #4*: Git repo with modifications
dhend...@thegates:flashrom$ ./util/getrevision.sh -u -l -t -U
1130
b388227
Sep 07 2010 21:53:31 UTC
ssh://[email protected]/flashrom

dhend...@thegates:flashrom$ sudo ./flashrom --version
flashrom v0.9.2-r1130 from ssh://[email protected]/flashrom, local
revision b388227, timestamp Sep 07 2010 15:22:38 +,  on Linux
2.6.32-14-generic (x86_64), built with libpci 3.0.0, GCC 4.4.3, little
endian
flashrom is free software, get the source code at http://www.flashrom.org

Signed-Off-By: David Hendricks <[email protected]>

-- 
David Hendricks (dhendrix)
Systems Software Engineer, Google Inc.
Index: flashrom-gitfriendly/util/getrevision.sh
===================================================================
--- /dev/null
+++ flashrom-gitfriendly/util/getrevision.sh
@@ -0,0 +1,227 @@
+#!/bin/sh
+#
+# This file is part of the flashrom project.
+#
+# Copyright (C) 2005 coresystems GmbH <[email protected]>
+# Copyright (C) 2009,2010 Carl-Daniel Hailfinger
+# Copyright (C) 2010 Chromium OS Authors
+#
+# 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+#
+
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+
+svn_revision() {
+    LC_ALL=C svnversion -cn . 2>/dev/null | \
+		sed -e "s/.*://" -e "s/\([0-9]*\).*/\1/" | \
+		grep "[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 ''
+}
+
+svn_url() {
+	echo $(LC_ALL=C svn info 2>/dev/null |
+		  grep URL: |
+		  sed 's/.*URL:[[:blank:]]*//' |
+		  grep ^.
+		 )
+}
+
+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} +")
+    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")
+    fi
+
+	echo "${timestamp}"
+}
+
+git_revision() {
+    echo $(git log --oneline | head -1 | awk '{print $1}')
+}
+
+# Retrieve svn revision using git log data (for git 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)
+        echo "${r}"
+}
+
+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} +")
+    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")
+    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 ^.
+		 )
+}
+
+scm_url() {
+	local url
+
+	if [ -d ".svn" ] ; then
+		url=$(svn_url)
+	elif [ -d ".git" ] ; then
+		url=$(git_url)
+	fi
+
+	echo "${url}"
+}
+
+# Retrieve timestamp since last modification. If the sources are pristine,
+# then the timestamp will match that of the SCM's more recent modification
+# date.
+timestamp() {
+	local t
+
+	if [ -d ".svn" ] ; then
+		t=$(svn_timestamp)
+	elif [ -d ".git" ] ; then
+		t=$(git_timestamp)
+	fi
+
+	echo ${t}
+}
+
+# Retrieve local SCM revision info. This is useful if we're working in
+# a even different SCM than upstream.
+#
+# 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)
+	fi
+
+	echo ${r}
+}
+
+# Get the upstream flashrom revision stored in SVN metadata.
+#
+# If the local copy is svn, then use svnversion
+# If the local copy is git, then scrape upstream revision from git logs
+upstream_revision() {
+	local r
+
+	if [ -d ".svn" ] ; then
+		r=$(svn_revision)
+	elif [ -d ".git" ] ; then
+		r=$(gitsvn_revision)
+	fi
+
+	echo "${r}"
+}
+
+show_help() {
+	echo "Usage:
+	${0} <option>
+
+Options
+    -h or --help
+        Display this message.
+    -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
+	"
+	return
+}
+
+if [ ! -n "${1}" ]
+then
+	show_help;
+	echo "No options specified";
+	exit ${EXIT_SUCCESS}
+fi
+
+# The is the main loop
+while [[ ${1} = -* ]];
+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)";
+		shift;;
+	-U|--url)
+		echo "$(scm_url)";
+		shift;;
+	*)
+		show_help;
+		echo "invalid option: ${1}"
+		exit ${EXIT_FAILURE}
+	esac;
+done
+
+exit ${EXIT_SUCCESS}
Index: Makefile
===================================================================
--- Makefile	(revision 1155)
+++ Makefile	(working copy)
@@ -97,7 +97,7 @@
 # of the checked out flashrom files.
 # Note to packagers: Any tree exported with "make export" or "make tarball"
 # will not require subversion. The downloadable snapshots are already exported.
-SVNVERSION := $(shell LC_ALL=C svnversion -cn . 2>/dev/null | sed -e "s/.*://" -e "s/\([0-9]*\).*/\1/" | grep "[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 unknown)
+SVNVERSION := $(shell ./util/getrevision.sh -u)
 
 RELEASE := 0.9.2
 VERSION := $(RELEASE)-r$(SVNVERSION)
Index: flashrom-gitfriendly/Makefile
===================================================================
--- flashrom-gitfriendly.orig/Makefile
+++ flashrom-gitfriendly/Makefile
@@ -97,13 +97,17 @@ all: pciutils features $(PROGRAM)$(EXEC_
 # of the checked out flashrom files.
 # Note to packagers: Any tree exported with "make export" or "make tarball"
 # will not require subversion. The downloadable snapshots are already exported.
-SVNVERSION := $(shell LC_ALL=C svnversion -cn . 2>/dev/null | sed -e "s/.*://" -e "s/\([0-9]*\).*/\1/" | grep "[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 unknown)
+UPSTREAMREV := $(shell ./util/getrevision.sh --upstream || echo unknown)
+LOCALREV := $(shell ./util/getrevision.sh --local)
+TIMESTAMP := $(shell ./util/getrevision.sh --timestamp)
+SCMURL := $(shell ./util/getrevision.sh --url || echo unknown )
 
 RELEASE := 0.9.2
-VERSION := $(RELEASE)-r$(SVNVERSION)
+VERSION := $(RELEASE)-r$(UPSTREAMREV)
 RELEASENAME ?= $(VERSION)
 
-SVNDEF := -D'FLASHROM_VERSION="$(VERSION)"'
+SCMDEF := -D'FLASHROM_VERSION="$(VERSION)"' -D'FLASHROM_SCMURL="$(SCMURL)"' \
+          -D'FLASHROM_LOCALREV="$(LOCALREV)"' -D'FLASHROM_TIMESTAMP="$(TIMESTAMP)"'
 
 # Always enable internal/onboard support for now.
 CONFIG_INTERNAL ?= yes
@@ -323,7 +327,7 @@ $(PROGRAM)$(EXEC_SUFFIX): $(OBJS)
 TAROPTIONS = $(shell LC_ALL=C tar --version|grep -q GNU && echo "--owner=root --group=root")
 
 %.o: %.c .features
-	$(CC) -MMD $(CFLAGS) $(CPPFLAGS) $(FEATURE_CFLAGS) $(SVNDEF) -o $@ -c $<
+	$(CC) -MMD $(CFLAGS) $(CPPFLAGS) $(FEATURE_CFLAGS) $(SCMDEF) -o $@ -c $<
 
 # Make sure to add all names of generated binaries here.
 # This includes all frontends and libflashrom.
@@ -433,9 +437,12 @@ install: $(PROGRAM)$(EXEC_SUFFIX)
 
 export:
 	@rm -rf $(EXPORTDIR)/flashrom-$(RELEASENAME)
-	@svn export -r BASE . $(EXPORTDIR)/flashrom-$(RELEASENAME)
-	@sed "s/^SVNVERSION.*/SVNVERSION := $(SVNVERSION)/" Makefile >$(EXPORTDIR)/flashrom-$(RELEASENAME)/Makefile
-	@LC_ALL=C svn log >$(EXPORTDIR)/flashrom-$(RELEASENAME)/ChangeLog
+	@svn export -r BASE . $(EXPORTDIR)/flashrom-$(RELEASENAME) 2>/dev/null || git checkout-index -a -f --prefix=$(EXPORTDIR)/flashrom-$(RELEASENAME)/
+	@# If SCMVERSION or SCMEXTVERSION contain a slash or SCMURL contains a hash, this will explode
+	@sed "s/^SCMVERSION.*/SCMVERSION := $(SCMVERSION)/;s/^SCMEXTVERSION.*/SCMEXTVERSION := $(SCMEXTVERSION)/;s#^SCMURL.*#SCMURL := $(SCMURL)#" Makefile >$(EXPORTDIR)/flashrom-$(RELEASENAME)/Makefile
+	@# ChangeLog should be in English, but we want UTF-8 for names.
+	@( LC_ALL=en_US.UTF-8 svn log 2>/dev/null || LC_ALL=en_US.UTF-8 git log 2>/dev/null || echo "Unable to extract log from SCM" ) >$(EXPORTDIR)/flashrom-$(RELEASENAME)/ChangeLog
+	@rm -f $(EXPORTDIR)/flashrom-$(RELEASENAME)/.gitignore $(EXPORTDIR)/flashrom-$(RELEASENAME)/.gitattributes $(EXPORTDIR)/flashrom-$(RELEASENAME)/.gitmodules
 	@echo Exported $(EXPORTDIR)/flashrom-$(RELEASENAME)/
 
 tarball: export
Index: flashrom-gitfriendly/flashrom.c
===================================================================
--- flashrom-gitfriendly.orig/flashrom.c
+++ flashrom-gitfriendly/flashrom.c
@@ -1377,6 +1377,12 @@ void print_sysinfo(void)
 void print_version(void)
 {
 	msg_ginfo("flashrom v%s", flashrom_version);
+	msg_ginfo(" from %s", FLASHROM_SCMURL);
+	if (!strcmp(FLASHROM_LOCALREV, ""))
+		msg_ginfo(", no local revision");
+	else
+		msg_ginfo(", local revision %s", FLASHROM_LOCALREV);
+	msg_ginfo(", timestamp %s, ", FLASHROM_TIMESTAMP);
 	print_sysinfo();
 }
 
_______________________________________________
flashrom mailing list
[email protected]
http://www.flashrom.org/mailman/listinfo/flashrom

Reply via email to