Mercurial > pylearn
view version.py @ 323:44f94ffe28f7
version works with file and folder, returns null if not in hg. Also a function to get all modules, but seems to get junk at the same time
author | Thierry Bertin-Mahieux <bertinmt@iro.umontreal.ca> |
---|---|
date | Thu, 12 Jun 2008 17:12:45 -0400 |
parents | 9ebc960260c5 |
children | ce79bf5fa463 |
line wrap: on
line source
import subprocess as _subprocess import imp as _imp import sys import os _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. """ if module_name not in _cache: try : location = _imp.find_module(module_name)[1] except ImportError: _cache[module_name] = None return None #print 'location:', location isdir = False if os.path.isdir(location) : isdir = True elif os.path.isfile(location) : isdir = False else : # SEEMS THIS CASE EXIST, FOR WEIRD BUILTIN FUNCTIONS #print location,": it's 'not a dir, it's not a file, it's superman!" #raise Exception('Unknown location or file type') _cache[module_name] = None return None # we're dealing with a dir if isdir : # under hg? if not os.path.exists( os.path.join( location , '.hg') ) : _cache[module_name] = None return None status = _subprocess.Popen(('hg','st'),cwd=location,stdout=_subprocess.PIPE).communicate()[0] #print 'status =', status #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] # we're dealing with a file if not isdir : folder = os.path.split( os.path.abspath(location) )[0] # under hg? if not os.path.exists( os.path.join( folder , '.hg') ) : _cache[module_name] = None return None status = _subprocess.Popen(('hg','st',location),cwd=folder,stdout=_subprocess.PIPE).communicate()[0] #print 'status =', status #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:], location,folder)) if line[0] == '?' and line[-3:] == '.py': raise Exception('Untracked file "%s" in %s (%s)' %(line[2:], location, folder)) hg_id = _subprocess.Popen(('hg','id'),cwd=folder,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 if tokens[0][-1] == '+' : tokens[0] = tokens[0][:-1] # the change was not on this file if len(tokens) == 2: assert tokens[1] == 'tip\n' _cache[module_name] = tokens[0] return _cache[module_name] def get_all_src_versions() : """ Get the version of all loaded module. Calls src_version on all loaded modules. These modules are found using sys.modules. Returns a dictionnary: name->version. @RETURN dict Dictionnary (module's name) -> (version) @SEE src_version """ allmodules = sys.modules d = dict() for m in allmodules : d[m] = src_version(m) return d if __name__ == "__main__" : if len(sys.argv) == 2 : print 'testing on', sys.argv[1] print src_version(sys.argv[1])