view version.py @ 311:0690de82c338

a lot of tests are broken because of the new behaviour of __getitem__ that always returns a LookupList, working on that...
author Thierry Bertin-Mahieux <bertinmt@iro.umontreal.ca>
date Wed, 11 Jun 2008 12:45:24 -0400
parents 9ebc960260c5
children 44f94ffe28f7
line wrap: on
line source

import subprocess as _subprocess
import imp as _imp

_cache = {}

def src_version(module_name):
    """Return compact identifier of module code.

    @return: compact identifier of module code.
    @rtype: string

    @note: This function tries to establish that the source files and the repo
    are syncronized.  It raises an Exception if there are un-tracked '.py'
    files, or if there are un-committed modifications.  This implementation uses
    "hg id" to establish this.  The code returned by "hg id" is not affected by
    hg pull, but pulling might remove the " tip" string which might have
    appeared.  This implementation ignores the  " tip" information, and only
    uses the code.

    @note: This implementation is assumes that the import directory is under
    version control by mercurial.

    """
    #
    # NOTE
    #
    # If you find bugs in this function, please update the __src_version__
    # function in theano, pylearn, and email either theano-dev or pylearn-dev so
    # that people can update their experiment dirs (the output of this function
    # is meant to be hard-coded in external files).
    #

    if module_name not in _cache:

        location = _imp.find_module(module_name)[1]
        #print 'location:', location

        status = _subprocess.Popen(('hg','st'),cwd=location,stdout=_subprocess.PIPE).communicate()[0]
        #TODO: check that the process return code is 0 (ticket #45)

        #status_codes = [line[0] for line in  if line and line[0] != '?']
        for line in status.split('\n'):
            if not line: continue
            if line[0] != '?':
                raise Exception('Uncommitted modification to "%s" in %s (%s)'
                        %(line[2:], __name__,location))
            if line[0] == '?' and line[-3:] == '.py':
                raise Exception('Untracked file "%s" in %s (%s)'
                        %(line[2:], __name__, location))

        hg_id = _subprocess.Popen(('hg','id'),cwd=location,stdout=_subprocess.PIPE).communicate()[0]

        #This asserts my understanding of hg id return values
        # There is mention in the doc that it might return two parent hash codes
        # but I've never seen it, and I dont' know what it means or how it is
        # formatted.
        tokens = hg_id.split(' ')
        assert len(tokens) <= 2
        assert len(tokens) >= 1
        assert tokens[0][-1] != '+' # the trailing + indicates uncommitted changes
        if len(tokens) == 2:
            assert tokens[1] == 'tip\n'

        _cache[module_name] = tokens[0]

    return _cache[module_name]