Hi, as far as I know, no. But I agree it would be great to have, and
is certainly possible to do.
If Rich would be willing to add this to boot.clj,
(defn clojure-svn-revision []
(if-let rev (re-find #"Rev: (\d+) \$" "$Rev$")
(second rev)
"unknown"))
and then do this,
svn propset svn:keywords "Revision" boot.clj
svn commit boot.clj
...then (clojure-svn-revision) ought to return the revision number as
a string.
Best,
Graham
Yes, exactly. See
http://svnbook.red-bean.com/en/1.1/ch07s02.html
in the "keywords" section.
Best,
Graham
I'd really like to see something like this too, but unfortunately I
don't think it's this simple.
Please correct me if I'm wrong, but any changes to the Clojure sources
that don't include a change to boot.clj will fail to update this
revision number. If that's the case, the number reported could be
misleading, and I'd argue would be worse than no number at all.
I think the "right" way to do this would be for the Clojure compile
process to include a call out to "svn info" to get the revision number
of the whole tree, and then somehow include the results of that back
in the .jar file for some Clojure function to read. ...but I don't
really know enough about ant (or svn either, for that matter) to do
this myself.
--Chouser
Oh, excellent point.
> I think the "right" way to do this would be for the Clojure compile
> process to include a call out to "svn info" to get the revision number
> of the whole tree, and then somehow include the results of that back
> in the .jar file for some Clojure function to read. ...but I don't
> really know enough about ant (or svn either, for that matter) to do
> this myself.
I suspect there is a better way than that -- we shouldn't really
depend upon the client to have 'svn' installed at build-time, though
it would often be the case.
Subversion supports 'hook scripts' that are run server-side during a
commit process. I'm sure someone else has written such a script to
update a version-file (e.g. version.clj, containing a *version* def)
that is touched any time a revision is made.
Let me see what I can find.
Graham
If someone is building from source, I think we can assume they have
development tools.
-Matt
For instance, there's a mirror on github.
>
> This wouldn't work if someone is using a mirror of the repository
> using a different SCM.
>
> For instance, there's a mirror on github.
True, if supporting other SCMs is important we can make the "version"
task in the build file smart enough to determine which, if any, should
be used for requesting the version. The other option is to add a
commit hook that will update the contents of some file with the
current revision. The latter option is starting to sound better.
No, but it would still include the upstream SVN revision number.
Alas, what I thought was possible with SVN hooks appears to be
impossible -- while in an SVN commit transaction, the SVN server
cannot say "and also touch this file over here" if that file was not
part of the commited patch.
It seems the best alternative is to let Ant try to get the SVN
revision and push in the change, as Chouser suggested.
Best,
Graham
Index: build.xml
===================================================================
--- build.xml (revision 1088)
+++ build.xml (working copy)
@@ -11,6 +11,7 @@
<property name="build" location="classes"/>
<property name="clojure_jar" location="clojure.jar"/>
<property name="bootclj" location="${cljsrc}/clojure/boot.clj"/>
+ <property name="versioninfo" location="versioninfo"/>
<target name="init">
<tstamp/>
@@ -22,10 +23,18 @@
<javac srcdir="${jsrc}" destdir="${build}"
includeJavaRuntime="yes" debug="true" target="1.5"/>
</target>
- <target name="jar" depends="compile"
+ <target name="version"
+ description="Generate version information file.">
+ <exec executable="svnversion" spawn="false" dir="."
output="${versioninfo}">
+ <arg line="."/>
+ </exec>
+ </target>
+
+ <target name="jar" depends="compile, version"
description="Create jar file.">
<jar jarfile="${clojure_jar}" basedir="${build}">
<fileset dir="${cljsrc}" includes="**/*.clj"/>
+ <fileset dir="." includes="**/versioninfo"/>
<manifest>
<attribute name="Main-Class" value="clojure.lang.Repl"/>
<attribute name="Class-Path" value="."/>
Index: src/clj/clojure/boot.clj
===================================================================
--- src/clj/clojure/boot.clj (revision 1088)
+++ src/clj/clojure/boot.clj (working copy)
@@ -3674,3 +3674,4 @@
"defs the supplied var names with no bindings, useful for making
forward declarations."
[& names] `(do ~@(map #(list 'def %) names)))
+(def *version* (. (java.io.BufferedReader.
(java.io.InputStreamReader. (ClassLoader/getSystemResourceAsStream
"versioninfo"))) readLine))
user> *version*
"1088M"
The build.xml script now runs a version task that creates a
"versioninfo" file. That file is added to clojure.jar and read in
boot.clj where the value is stored in *version*.
-Matt
The only problem is that the build script now depends on the
"svnversion" command being available and a SVN repository being used
for building. For tarball releases of the source, the "versioninfo"
file can be generated for the release and the build script modified to
use the existing file if "svnversion" isn't working. As for
supporting git and other SCMs used to mirror the SVN repos, the build
script can be made to use the tools available in any of the other SCMs
to identify the SVN revision and generate the "versioninfo" file.
Or have we decided this isn't worth it?
-Matt
+1. I think it's worth it, and would really like to see this put in place.
Best,
Graham