[PATCH] Fix how setup.py identifies the Mercurial version

Jeremy Whitlock jcscoobyrs at gmail.com
Thu Apr 2 19:02:40 CDT 2009


On Thu, Apr 2, 2009 at 5:06 PM, Jeremy Whitlock <jcscoobyrs at gmail.com> wrote:
> # HG changeset patch
> # User Jeremy Whitlock <jcscoobyrs at gmail.com>
> # Date 1238713536 21600
> # Node ID bbc8f6c436ca93681aeaef353475ea6022c145d1
> # Parent  67e59a9886d5902de5b94cd2552d854b6292ec63
> Fix how setup.py identifies the Mercurial version.
>
> There is a problem with setup.py where it will not identify the Mercurial
> version properly when not being ran in within a repository even if
> mercurial/__version__.py exists.
>
> To fix, use mercurial.util.version() to get the version number.
>
> diff -r 67e59a9886d5 -r bbc8f6c436ca setup.py
> --- a/setup.py  Thu Mar 26 19:01:06 2009 +0900
> +++ b/setup.py  Thu Apr 02 17:05:36 2009 -0600
> @@ -97,10 +97,7 @@
>  except ImportError:
>     pass
>
> -def getversion():
> -    if not os.path.exists('.hg'):
> -        return None # not in a repository
> -
> +if os.path.exists('.hg'):
>     # execute hg out of this directory with a custom environment which
>     # includes the pure Python modules in mercurial/pure
>     pypath = os.environ.get('PYTHONPATH', '')
> @@ -108,6 +105,7 @@
>     os.environ['PYTHONPATH'] = os.pathsep.join(['mercurial', purepath, pypath])
>     os.environ['HGRCPATH'] = '' # do not read any config file
>     cmd = '%s hg id -it' % sys.executable
> +    version = None
>
>     try:
>         l = os.popen(cmd).read().split()
> @@ -122,16 +120,16 @@
>         version = l[-1] # latest tag or revision number
>         if version.endswith('+'):
>             version += time.strftime('%Y%m%d')
> -        return version
>
> -version = getversion()
> -if version:
> -    f = file("mercurial/__version__.py", "w")
> -    f.write('# this file is autogenerated by setup.py\n')
> -    f.write('version = "%s"\n' % version)
> -    f.close()
> -else:
> -    version = "unknown"
> +    if version:
> +        f = file("mercurial/__version__.py", "w")
> +        f.write('# this file is autogenerated by setup.py\n')
> +        f.write('version = "%s"\n' % version)
> +        f.close()
> +
> +from mercurial import util
> +
> +version = util.version()
>
>  class install_package_data(install_data):
>     def finalize_options(self):
>

Looks like this creates a dependency issue.  setup.py is used to build
Mercurial and until mercurial is built, using mercurial.util.version()
won't work because osutil cannot be found.  So if Mercurial hasn't
been built, you'll end up with something like this:

python setup.py --version
Traceback (most recent call last):
  File "setup.py", line 130, in <module>
    from mercurial import util
  File "/private/tmp/mercurial-1.2.1/mercurial/util.py", line 17, in <module>
    import os, stat, threading, time, calendar, ConfigParser, locale,
glob, osutil
ImportError: No module named osutil

When trying "python setup.py build" or "make local", you end up with a
much longer traceback but the cause is the same.  Looks like using
mercurial.util.version() will not be an option.  We can fix this by
either refactoring the to remove the dependency issue or by using the
following in setup.py:

...
try:
    from mercurial import __version__
    version = __version__.version
except ImportError:
    version = 'unknown'
...

in place of:

...
from mercurial import util

version = util.version()
...

The only problem with this approach is maintainability.  We'd need to
make sure that whatever code we use for mercurial.util.version() is
kept up to date with what is in setup.py.  Thoughts?

-- 
Take care,

Jeremy Whitlock
http://www.thoughtspark.org



More information about the Mercurial-devel mailing list