Implementation Version

7 views
Skip to first unread message

Parth Malwankar

unread,
Aug 13, 2008, 1:04:46 AM8/13/08
to Clojure
Hello,

Is there something like a lisp-implementation-version or similar in
Clojure that tells us what version (or svn rev) we are running?

CL-USER(1): (lisp-implementation-version)
"1.0.18.debian"

Thanks.
Parth

Allen Rohner

unread,
Aug 13, 2008, 1:34:00 PM8/13/08
to Clojure


On Aug 13, 12:04 am, Parth Malwankar <parth.malwan...@gmail.com>
wrote:
> Hello,
>
> Is there something like a lisp-implementation-version or similar in
> Clojure that tells us what version (or svn rev) we are running?
>

There isn't yet, but that's a good idea. It should be pretty easy.
Rich, do you have any suggestions for how you would like to see this
done? I think I could take that on.

Allen


Rich Hickey

unread,
Aug 13, 2008, 10:21:20 PM8/13/08
to Clojure
I'm open to suggestions for any completely automated solution based
around my current workflow, which is just basic SVN checkins.

Rich

Chouser

unread,
Aug 13, 2008, 10:37:10 PM8/13/08
to clo...@googlegroups.com
On Wed, Aug 13, 2008 at 10:21 PM, Rich Hickey <richh...@gmail.com> wrote:
>
> I'm open to suggestions for any completely automated solution based
> around my current workflow, which is just basic SVN checkins.

It seems to me there are a lot of cases where a version number doesn't
really make sense. Unless it's a release clojure.jar, there could be
local changes, non-SVN repositories (I use git, others use mercurial),
etc. in which case an SVN repo version number could be misleading.

I guess it depends on what the version number would be used for.

--Chouser

Shawn Hoover

unread,
Aug 14, 2008, 2:35:34 AM8/14/08
to clo...@googlegroups.com

It's nice to have some unique version available in release jars, and, given that a lot of people build from source, I can see the value of using a Subversion revision. But I would like to hear more about if it's needed in programs and if so for what purpose--if you build from source and you want to know the version while you're working interactively, it's just as easy to run svnversion or svn info or log.

That said, Subversion does make it easy to get the latest revision number for a given file with no additional workflow, by using the Rev keyword in the file and setting the svn:keywords property on the file. (http://svnbook.red-bean.com/en/1.4/svn.advanced.props.special.keywords.html)

(def rev "$Rev$") in source would be substituted automatically to (def rev "$Rev: 9991 $") at checkout or export and is easily parsed with a regex. This technique would work reasonably well for non-svn repositories: whatever mechanism they use to get the source out of svn (svn checkout, svn export) will translate the keyword, so you'll always have access to the revision that your local changes are based on.

Unfortunately, though, that only gives you the latest revision for that single file. To guarantee a unique project-wide revision we'd have to wrap svn commit into an ant task that first runs svnversion or svn info and does a text replacement. So again it comes down to what the need is and whether it's worth it.

Shawn

Parth Malwankar

unread,
Aug 14, 2008, 3:38:04 AM8/14/08
to Clojure


On Aug 14, 11:35 am, "Shawn Hoover" <shawn.hoo...@gmail.com> wrote:
> On Wed, Aug 13, 2008 at 7:37 PM, Chouser <chou...@gmail.com> wrote:
>
> > On Wed, Aug 13, 2008 at 10:21 PM, Rich Hickey <richhic...@gmail.com>
> > wrote:
>
> > > I'm open to suggestions for any completely automated solution based
> > > around my current workflow, which is just basic SVN checkins.
>
> > It seems to me there are a lot of cases where a version number doesn't
> > really make sense.  Unless it's a release clojure.jar, there could be
> > local changes, non-SVN repositories (I use git, others use mercurial),
> > etc. in which case an SVN repo version number could be misleading.
>
> > I guess it depends on what the version number would be used for.
>
> It's nice to have some unique version available in release jars, and, given
> that a lot of people build from source, I can see the value of using a
> Subversion revision. But I would like to hear more about if it's needed in
> programs and if so for what purpose--if you build from source and you want
> to know the version while you're working interactively, it's just as easy to
> run svnversion or svn info or log.
>
> That said, Subversion does make it easy to get the latest revision number
> for a given file with no additional workflow, by using the Rev keyword in
> the file and setting the svn:keywords property on the file. (http://svnbook.red-bean.com/en/1.4/svn.advanced.props.special.keyword...)
>
> (def rev "$Rev$") in source would be substituted automatically to (def rev
> "$Rev: 9991 $") at checkout or export and is easily parsed with a regex.
> This technique would work reasonably well for non-svn repositories: whatever
> mechanism they use to get the source out of svn (svn checkout, svn export)
> will translate the keyword, so you'll always have access to the revision
> that your local changes are based on.
>
> Unfortunately, though, that only gives you the latest revision for that
> single file. To guarantee a unique project-wide revision we'd have to wrap
> svn commit into an ant task that first runs svnversion or svn info and does
> a text replacement. So again it comes down to what the need is and whether
> it's worth it.
>
> Shawn

I feel a command like this with a little more info than
just the revision number can be very useful.

A (version) command could give compile time as well as
some runtime info. It could be something on the lines of
Python's sys.version_info

>>> sys.version_info
(2, 5, 2, 'final', 0)

E.g.
user => (version)
{:version N.NN ; compile time
:revison 999 ; compile time
:date (2008 10 12 ... time ...) ; compile time
:java "1.06.0_06" ; runtime
:platform "linux ..."
: ... other useful stuff ... }

Some use cases that come to mind are:

1. I create a clj script and hand it over to someone else and it
fails,
it could be that there is some other rev of Clojure installed on
that system that doesn't have API (xxx).
I could tell that user to check "svn info" the clojure version
or I could simply put in the script a check:
(if (< (:revision (version)) 999) (complain ...))

This would make distributing the script easier.

Also, there may be some people who just use clojure 20080612.
That confuses things a little more.

2. Consider a bug like this
http://groups.google.com/group/clojure/browse_thread/thread/a4e1b58061962479
which came up a few days back. It was related to changes
in the JVM (which I don't understand as I am a not a Java guy).
To help report if the problem is reproducible by me, I am not
very sure how to get the java version info short of using the
apt command on my debian system to see what package is installed.
(I was too lazy to do this hence you won't find this info
with my mail on the thread :-P)

If all the relevant info can be put together under one command
then in case of some failure the user can just do (version) and
the dev-team has all the required stuff to narrow down the problem.

3. I have burnt my fingers with Python a few times when there were
multiple python packages installed on the system and the wrong
one was getting picked up. The error was later narrowed down to
bad PYTHONPATH. Other such useful info can also be printed by
the (version) API.

Another example is the :version command for Vim. It contains
a lot of info about things like version number, what rc
file is being picked up etc. You will find on the vim_dev list
that any bug report inevitably have the output of :version
command attached as it makes it much easier to understand whats
going on.

That said, yes its possible to get all this info by other ways,
(svn info, aptitude search, probably a function call in Java
for version) but for a lay user it would be much nicer if one can
just run (version). And for programmers (clojure users - not
clojure devs), the could ensure their clojure script exit cleanly
at if the script user has some incompatibility with the version
installed. For the clojure-devs it could have additional info
required to narrow down any potential bugs.

Parth

lpetit

unread,
Aug 14, 2008, 5:29:05 AM8/14/08
to Clojure
Hello,

Numbering could also be achieved for official releases by "tagging"
the trunk : doing a copy of the trunk to a directory named after the
release version, e.g. for a release number 0.4.3 (or 20080812 if you
prefer versioning by date) :
svn cp <repo>/trunk <repo>/tags/0.4.3

You could then use keyword substitution with the Keyword $URL$ that
will give :
- either a path to the trunk to mean that you're executing something
not officially released (and there the $Rev$ keyword could help
identify the revision of individual files),
- either a path to a versioned directory in tags : that would give the
hint that this is an official release, and the last part of the path
will give the release version.

HTH,

--
Laurent
>    http://groups.google.com/group/clojure/browse_thread/thread/a4e1b5806...

lpetit

unread,
Aug 14, 2008, 5:47:40 AM8/14/08
to Clojure
Hello again,

On 14 août, 09:38, Parth Malwankar <parth.malwan...@gmail.com> wrote:
> 1. I create a clj script and hand it over to someone else and it
> fails,
>    it could be that there is some other rev of Clojure installed on
>    that system that doesn't have API (xxx).
>    I could tell that user to check "svn info" the clojure version
>    or I could simply put in the script a check:
>    (if (< (:revision (version)) 999) (complain ...))

Well I'm not sure this would work well if users are compiling a
version that they checkout themselves : what revision version should
be considered, then ?
Indeed, for this to work, it would be necessary to place a revision
keyword on each and every file, and then grep all files to find their
revision number, and retain the highest number ... Error prone I
think.

One solution could be to have an alternative in the build script to do
a clean checkout or export before the build, go into the exported /
checkout directory, and run the build in there. There, there would be
an opportunity to get the revision number in the checkout/export
phase.
This process also has the advantage of being sure that we did a
reproducible build since the checkout was from a clearly identified
svn revision.

>    This would make distributing the script easier.
>
>    Also, there may be some people who just use clojure 20080612.
>    That confuses things a little more.

This could be resolved if 20080612 was identified as an official
release in svn, e.g. there was a directory called tags/20080612. Then
it could be possible to have a simple script to get the "official
release version" by parsing the $URL$ keyword in some central file :
either the keyword refers to the trunk, and the official release
function would return nil or "", either the keyword refers to
directory tags, and the function would return 20080612.

As for extracting the revision number from the official release
number, this is not so easy. It could be possible dynamically but then
one should be expected to have an svn command line installed, and its
user / password already cached by svn.
And then, getting the log for tags/20080612 would say something like :
copied into tags/20080612/ in revision xxx from trunk/ in revision
yyyy => yyyy would give you the revision number of the release.

Of course, this works iff you use tags directory as expected : just
for copying from the trunk, and never ever directly working in it
(commiting) after the copy.

>
> 2. Consider a bug like this
>    http://groups.google.com/group/clojure/browse_thread/thread/a4e1b5806...

Parth Malwankar

unread,
Aug 14, 2008, 6:16:12 AM8/14/08
to Clojure
One approach I have seen used is to have a separate file
(e.g. version.clj) that would be 'touched' and automatically be
checked in via a check-in hook script. This file would have the
relevant keywords and is case, possibly the function 'version'.

One caution though that hook script has to take is _not_ to
run if the file being checked in is version.clj. I am not sure
how this was done as the hook script wasn't written by me.
I have seen this approach being used on a svn based system.

Shawn Hoover

unread,
Aug 14, 2008, 2:29:25 PM8/14/08
to clo...@googlegroups.com
On Thu, Aug 14, 2008 at 12:38 AM, Parth Malwankar <parth.m...@gmail.com> wrote:
I feel a command like this with a little more info than
just the revision number can be very useful.

A (version) command could give compile time as well as
some runtime info. It could be something on the lines of
Python's sys.version_info

>>> sys.version_info
(2, 5, 2, 'final', 0)

E.g.
user => (version)
{:version N.NN                      ; compile time
 :revison 999                       ; compile time
 :date    (2008 10 12 ... time ...) ; compile time
 :java    "1.06.0_06"               ; runtime
 :platform "linux ..."
 : ... other useful stuff ... }

Parth, I agree your use cases are valuable.

Here is a def that provides most of the information you list above. Compile time is ambiguous since Clojure compiles Clojure code on the fly; on the other hand the Java classes are compiled at release time.

(def
  #^{:doc "A map of the Clojure and Java runtime versions."}
  rt-version (array-map
              :major 0
              :minor 1
              :rev (. Integer parseInt (second (re-find #"\\$Rev: (\\d+) \\$"
                                                        "$Rev: 999 $")))
              :java (str (. System getProperty "java.version") " "
                         (. System getProperty "java.vm.name"))
              :system (str (. System getProperty "os.arch") " "
                           (. System getProperty "os.name") " "
                           (. System getProperty "os.version"))))

On my system this evaluates to:
{:major 0, :minor 1, :rev 999, :java "1.6.0_07 Java HotSpot(TM) Client VM", :system "x86 Windows Vista 6.0"}

I envision this in boot.clj, so for Rich's normal workflow $Rev$ would be unique for revisions of that file. Major and minor would be modified manually. An official release script could substitute a project-wide revision prior to packing the jar.

I made it an array-map so the ordering is preserved in order of (my opinion of) importance. I would be interested in hearing ideas for how to make clojure/print output just "Clojure 0.1.999, Java 1.6.0_07 Java HotSpot(TM) Client VM".

Shawn

Allen Rohner

unread,
Aug 14, 2008, 2:36:38 PM8/14/08
to Clojure
On Aug 14, 1:29 pm, "Shawn Hoover" <shawn.hoo...@gmail.com> wrote:
> On Thu, Aug 14, 2008 at 12:38 AM, Parth Malwankar <parth.malwan...@gmail.com
How would you handle Rev in the case of git-svn/mercurial?

Allen

Shawn Hoover

unread,
Aug 14, 2008, 2:51:27 PM8/14/08
to clo...@googlegroups.com
On Thu, Aug 14, 2008 at 11:36 AM, Allen Rohner <aro...@gmail.com> wrote:

On Aug 14, 1:29 pm, "Shawn Hoover" <shawn.hoo...@gmail.com> wrote:
> (def
>   #^{:doc "A map of the Clojure and Java runtime versions."}
>   rt-version (array-map
>               :major 0
>               :minor 1
>               :rev (. Integer parseInt (second (re-find #"\\$Rev: (\\d+)
> \\$"
>                                                         "$Rev: 999 $")))
>               :java (str (. System getProperty "java.version") " "
>                          (. System getProperty "java.vm.name"))
>               :system (str (. System getProperty "os.arch") " "
>                            (. System getProperty "os.name") " "
>                            (. System getProperty "os.version"))))
How would you handle Rev in the case of git-svn/mercurial?

Allen

However you get the code out of Subversion, the Rev will be updated automatically at that time. For example, my Mercurial mirror essentially uses a Subversion checkout and "svn update" to get Rich's code. Every svn update modifies the Rev, and then Mercurial commits with the updated text.

Rev will stay true to the canonical repository, Sourceforge Subversion, which makes the most sense for bug reports. If I want Rev to reflect my local changes, I'd have to patch rt-version with an additional key and do something locally with Mercurial hooks.

Shawn

Parth Malwankar

unread,
Aug 14, 2008, 2:55:02 PM8/14/08
to Clojure


On Aug 14, 11:51 pm, "Shawn Hoover" <shawn.hoo...@gmail.com> wrote:
I came across this interesting article on build using Maven that seem
to be doing what we want.
http://binil.wordpress.com/2006/12/16/stamping-qa-builds-with-svn-revision-number/

Parth

Parth Malwankar

unread,
Aug 14, 2008, 3:08:03 PM8/14/08
to Clojure


On Aug 14, 11:29 pm, "Shawn Hoover" <shawn.hoo...@gmail.com> wrote:
> On Thu, Aug 14, 2008 at 12:38 AM, Parth Malwankar <parth.malwan...@gmail.com
The def looks very useful. Thanks Shawn.
Its going into my rc :)

Parth Malwankar

unread,
Aug 14, 2008, 3:28:33 PM8/14/08
to Clojure

> I made it an array-map so the ordering is preserved in order of (my opinion
> of) importance. I would be interested in hearing ideas for how to make
> clojure/print output just "Clojure 0.1.999, Java 1.6.0_07 Java HotSpot(TM)
> Client VM".
>

Not sure if there is a better way to do it but based on your def here
is what I put in my rc:

(def
#^{:doc "A map of the Clojure and Java runtime versions."}
rt-version (array-map
:major 0
:minor 1
:rev (. Integer parseInt
(second (re-find #"\\$Rev: (\\d+) \\$" "$Rev:
999 $")))
:java (str (. System getProperty "java.version") " "
(. System getProperty "java.vm.name"))
:system (str (. System getProperty "os.arch") " "
(. System getProperty "os.name") " "
(. System getProperty "os.version"))
:long-version (fn []
(str "Clojure "
(rt-version :major) "."
(rt-version :minor) " r"
(rt-version :rev) " "
(rt-version :java) " "
(rt-version :system)))))

(def rt-version-str (rt-version :long-version))

So we have an rt-version for programming use, and
(rt-version-str) that can be used to get a complete string.

user=> rt-version
{:major 0, :minor 1, :rev 999, :java "1.6.0_07 Java HotSpot(TM)
Client VM", :system "i386 Linux 2.6.22-2-686", :long-version
user.fn__2136@a030d6}

user=> (rt-version-str)
"Clojure 0.1 r999 1.6.0_07 Java HotSpot(TM) Client VM i386 Linux
2.6.22-2-686"
user=>

(rt-version-str) or a variation could possibly be called on startup so
that
the REPL message becomes

Clojure 0.1 r999 1.6.0_07 Java HotSpot(TM) Client VM
user=>

Parth

Shawn Hoover

unread,
Aug 14, 2008, 6:41:40 PM8/14/08
to clo...@googlegroups.com
On Thu, Aug 14, 2008 at 12:28 PM, Parth Malwankar <parth.m...@gmail.com> wrote:
> I made it an array-map so the ordering is preserved in order of (my opinion
> of) importance. I would be interested in hearing ideas for how to make
> clojure/print output just "Clojure 0.1.999, Java 1.6.0_07 Java HotSpot(TM)
> Client VM".
>
   user=> (rt-version-str)

   "Clojure 0.1 r999 1.6.0_07 Java HotSpot(TM) Client VM i386 Linux
2.6.22-2-686"
   user=>

That's basically what I wanted. I'm trying to think of how I could do that with multimethods on print.

One caution, though: If (def rt-version ...) is in your rc file, how will major, minor, and rev get updated? It would have to be in Clojure's Subversion to get a unique value when Clojure is updated.

Shawn

Parth Malwankar

unread,
Aug 15, 2008, 3:00:23 AM8/15/08
to Clojure
Hello,

I did some playing around with the ant build script and here is
what the interaction can look like:

user=> version
{:major 0, :minor 1, :rev 999, :java "1.6.0_07 Java HotSpot(TM)
Client VM", :system "i386 Linux 2.6.22-2-686", :tstamp "15-Aug-08
12:02 PM", :short-version user.fn__2139@1f10a67, :long-version
user.fn__2142@1e2161d}

user=> (version-str)
"Clojure 0.1 r999 "

user=> (version-long-str)
"Clojure 0.1 r999 (1.6.0_07 Java HotSpot(TM) Client VM: i386
Linux 2.6.22-2-686: 15-Aug-08 12:02 PM)"
user=>

I have also added the time stamp above which might be handy
once official jars start going out.

As Shawn suggested, the API can probably be refined further
but this seems ok for now.

Basically, I created a file version_base.clj with the "version"
function
and two tags: subversion_revision and clj_build_stamp.

[parth:~/src/clojure]% grep "@" version_base.clj
:rev (new Integer "@subversion_revision@")
:tstamp "@clj_build_tstamp@"

To build.xml I added a task "make_version". This task creates a new
file "version.clj" from "version_base.clj" after substituting the
above tags for the relevant values.

This seems like a clean solution to me as there are no hook
scripts and stuff but there is one constraint.
This currently works only with subversion checkouts as "make_version"
uses "svn info" to extract revision number.

I looked at the git-svn but it seems git-svn basically keeps
the local copy in git format so "svn info" doesn't work there.
I am not an ant expert, possibly someone familier enough with
ant can comment if we can conditionally have the task take the
rev number using "git" command in case of a git repo and using
svn info in case of svn checkout.

Rich, is there someting like a "official" version control system
and an "official" build system (ant or maven) for Clojure.
IMHO supporting specialized builds across multiple version
control systems and build systems may turn out to be a bit of
a pain.

Rich, for now, I am using this feature by simply loading
version.clj in my rc file and this works fine.
If you see value in this feature and based on your project
priorities it would be nice if this can go somewhere in
the Clojure core so that any clojure.jar contains
"version" relates commands. Thanks.

Diffs and version_base.clj below.

Parth

[parth:~/src/clojure]% svn diff build.xml
Index: build.xml
===================================================================
--- build.xml (revision 999)
+++ build.xml (working copy)
@@ -12,7 +12,7 @@
<property name="clojure_jar" location="clojure.jar"/>
<property name="bootclj" location="${cljsrc}/clojure/boot.clj"/
>

- <target name="init">
+ <target name="init" depends="make_version">
<tstamp/>
<mkdir dir="${build}"/>
</target>
@@ -38,4 +38,22 @@
<delete dir="${build}"/>
</target>

+<target name="make_version" description="create version.clj from
version_base.clj">
+ <property name="revision" value="HEAD"/>
+ <exec executable="svn" output="rev.xml">
+ <arg line="info --xml"/>
+ </exec>
+ <xmlproperty file="rev.xml" collapseAttributes="true"/>
+ <echo>${info.entry.revision}</echo>
+ <tstamp>
+ <format property="clj_build_tstamp"
+ pattern="dd-MMM-yy hh:mm aa" unit="hour"/>
+ </tstamp>
+ <copy file="version_base.clj" tofile="version.clj">
+ <filterset begintoken="@" endtoken="@">
+ <filter token="subversion_revision" value="$
{info.entry.revision}"/>
+ <filter token="clj_build_tstamp" value="${clj_build_tstamp}"/>
+ </filterset>
+ </copy>
+</target>
</project>
[parth:~/src/clojure]% cat version_base.clj
(def
#^{:doc "A map of the Clojure and underlying system info."}
version (array-map
:major 0
:minor 1
:rev (new Integer "@subversion_revision@")
:java (str (. System getProperty "java.version") " "
(. System getProperty "java.vm.name"))
:system (str (. System getProperty "os.arch") " "
(. System getProperty "os.name") " "
(. System getProperty "os.version"))
:tstamp "@clj_build_tstamp@"
:short-version (fn []
(str "Clojure "
(version :major) "."
(version :minor) " r"
(version :rev) " "))
:long-version (fn []
(str ((version :short-version)) " ("
(version :java) ": "
(version :system) ": "
(version :tstamp) ")"))))

(def version-str (version :short-version))
(def version-long-str (version :long-version))

[parth:~/src/clojure]%


>
> Rich

Rich Hickey

unread,
Aug 15, 2008, 7:38:31 AM8/15/08
to Clojure
The official version control system is SVN on SourceForge, and the
official build script is ant.

> Rich, for now, I am using this feature by simply loading
> version.clj in my rc file and this works fine.
> If you see value in this feature and based on your project
> priorities it would be nice if this can go somewhere in
> the Clojure core so that any clojure.jar contains
> "version" relates commands. Thanks.
>
> Diffs and version_base.clj below.
>

Thanks!

If you haven't yet already done so, please submit a CA [1] so I can
evaluate including this.

Rich

[1] http://clojure.org/contributing

Parth Malwankar

unread,
Aug 16, 2008, 3:38:18 AM8/16/08
to Clojure
> > I looked at the git-svn but it seems git-svn basically keeps
> > the local copy in git format so "svn info" doesn't work there.
> > I am not an ant expert, possibly someone familier enough with
> > ant can comment if we can conditionally have the task take the
> > rev number using "git" command in case of a git repo and using
> > svn info in case of svn checkout.
>

Hello,

I did some more cleanup on the ant build.xml script to
have a workaround in place for version control systems
other than svn.

With the updated build, if the checkout is a svn
checkout we get the the correct revision number. If
its something else, revision number is seen as 0.
That seemed like a reasonable thing if the official
releases (jars) go out from a svn repository.

I suppose the end-user would prefer just using the
jars, and the people savvy enough to work with
bleeding edge release will know how to pull out
that bit of info. The other information is the same.

Unfortunately this the changes are just for ant
builds as I don't know much about maven.

Build in git-clojure checkout:
user=> (version-long-str)
"Clojure 0.1 r0 (1.6.0_07 Java HotSpot(TM) Client VM: i386 Linux
2.6.22-2-686: 16-Aug-08 12:51 PM)"
user=>

Build on a svn checkout:
user=> (version-long-str)
"Clojure 0.1 r1001 (1.6.0_07 Java HotSpot(TM) Client VM: i386
Linux 2.6.22-2-686: 16-Aug-08 12:55 PM)"
user=>

Below are the updated version_base.clj (currently just
put at the top level and "load-file"ed in my rc) and
the diff with the build.xml.

Comments / Suggestion (possibly on improving the version API
welcome. Thanks.

Parth


[parth:~/src/clojure]% cat version_base.clj
(def
#^{:doc "A map of the Clojure and underlying system info."}
version (array-map
:major 0
:minor 1
:rev (try (new Integer "@subversion_revision@")
(catch Exception e 0))
:java (str (. System getProperty "java.version") " "
(. System getProperty "java.vm.name"))
:system (str (. System getProperty "os.arch") " "
(. System getProperty "os.name") " "
(. System getProperty "os.version"))
:tstamp "@clj_build_tstamp@"
:short-version (fn []
(str "Clojure "
(version :major) "."
(version :minor) " r"
(version :rev) " "))
:long-version (fn []
(str ((version :short-version)) " ("
(version :java) ": "
(version :system) ": "
(version :tstamp) ")"))))

(def version-str (version :short-version))
(def version-long-str (version :long-version))

[parth:~/src/clojure]% svn diff build.xml
Index: build.xml
===================================================================
--- build.xml (revision 1001)
+++ build.xml (working copy)
@@ -12,18 +12,18 @@
<property name="clojure_jar" location="clojure.jar"/>
<property name="bootclj" location="${cljsrc}/clojure/boot.clj"/
>

- <target name="init">
+ <target name="init" depends="make_version">
<tstamp/>
<mkdir dir="${build}"/>
</target>

<target name="compile" depends="init"
- description="Compile Java sources.">
+ description="Compile Java sources.">
<javac srcdir="${jsrc}" destdir="${build}"
includeJavaRuntime="yes" debug="true"/>
</target>

<target name="jar" depends="compile"
- description="Create jar file.">
+ description="Create jar file.">
<jar jarfile="${clojure_jar}" basedir="${build}">
<fileset dir="${cljsrc}" includes="**/*.clj"/>
<manifest>
@@ -34,8 +34,40 @@
</target>

<target name="clean"
- description="Remove autogenerated files and
directories.">
+ description="Remove autogenerated files and
directories.">
+ <delete file="rev.xml"/>
+ <delete file="version.clj"/>
<delete dir="${build}"/>
</target>

+<target name="get_svn_info">
+ <exec executable="svn" output="rev.xml"
resultproperty="svn.info.result"
+ failifexecutionfails="false">
+ <arg line="info --xml"/>
+ </exec>
+ <echo>${svn.info.result}</echo>
+ <condition property="svn.info.ok">
+ <equals arg1="${svn.info.result}" arg2="0"/>
+ </condition>
+</target>
+
+<target name="get_rev_number" depends="get_svn_info"
if="svn.info.ok">
+ <xmlproperty file="rev.xml" collapseAttributes="true"/>
+</target>
+
+<target name="make_version" depends="get_rev_number"
+ description="create version.clj from version_base.clj">
+ <echo>${info.entry.revision}</echo>
+ <tstamp>
+ <format property="clj_build_tstamp"
+ pattern="dd-MMM-yy hh:mm aa" unit="hour"/>
+ </tstamp>
+ <copy file="version_base.clj" tofile="version.clj"
overwrite="true">
+ <filterset begintoken="@" endtoken="@">
+ <filter token="subversion_revision" value="$
{info.entry.revision}"/>
+ <filter token="clj_build_tstamp" value="${clj_build_tstamp}"/>
+ </filterset>
+ </copy>
+</target>
</project>
+
[parth:~/src/clojure]%

Parth Malwankar

unread,
Aug 16, 2008, 7:33:57 AM8/16/08
to Clojure


On Aug 16, 12:38 pm, Parth Malwankar <parth.malwan...@gmail.com>
wrote:
Hello,

I cleaned up the version command some more to have a unified (version)
function that supports everything including string. Below is the
interaction.

[parth:~]% clj
Clojure
user=> (version)
"Clojure 0.1 r1001"

user=> (version :long)
"Clojure 0.1 r1001 (1.6.0_07 Java HotSpot(TM) Client VM: i386
Linux 2.6.22-2-686: 16-Aug-08 04:58 PM)"

user=> (version :major)
0

user=> (version :minor)
1

user=> (version :rev)
1001

user=> (version :java)
"1.6.0_07 Java HotSpot(TM) Client VM"

user=> (version :system)
"i386 Linux 2.6.22-2-686"

user=> (version :tstamp)
"16-Aug-08 04:58 PM"

user=> version-map
{:major 0, :minor 1, :rev 1001, :java "1.6.0_07 Java HotSpot(TM)
Client VM", :system "i386 Linux 2.6.22-2-686", :tstamp "16-Aug-08
04:58 PM"}

user=> (version :xxx)
nil

Below is the new source for version_base.clj. Comments/suggestions
welcome.

Parth

[parth:~/src/clojure]% cat version_base.clj
(def
#^{:doc "A map of the Clojure and underlying system info."}
version-map (array-map
:major 0
:minor 1
:rev (try (new Integer "@subversion_revision@")
(catch Exception e 0))
:java (str (. System getProperty "java.version") " "
(. System getProperty "java.vm.name"))
:system (str (. System getProperty "os.arch") " "
(. System getProperty "os.name") " "
(. System getProperty "os.version"))
:tstamp "@clj_build_tstamp@"))

(defn version
([] (str "Clojure " (version :major) "." (version :minor)
" r" (version :rev)))
([x] (if (= x :long)
(str (version) " ("
(version :java) ": "
(version :system) ": "
(version :tstamp) ")")
(version-map x))))

[parth:~/src/clojure]%
Reply all
Reply to author
Forward
0 new messages