tools (utils): improved repository version detection:

- getRepositoryData has 2 new option: is_path to give absolute path instead of module name, and save_dir_path to save the repository data in a pickled dictionnary
    - if "hg" executable doesn't work, a .hg_data dictionnary is checked if present in module root path
This commit is contained in:
Goffi 2016-02-28 13:42:31 +01:00
commit 9de26f66ea

View file

@ -53,11 +53,22 @@ def xmpp_date(timestamp=None, with_time=True):
return datetime.datetime.utcfromtimestamp(time.time() if timestamp is None else timestamp).strftime(template)
def getRepositoryData(module, as_string=True):
def getRepositoryData(module, as_string=True, is_path=False, save_dir_path=None):
"""Retrieve info on current mecurial repository
@param module: module to look for (e.g. sat, libervia)
Data is gotten by using the following methods, in order:
- using "hg" executable
- looking for a ".hg_data" file in the root of the module
this file must contain the data dictionnary serialized with pickle
- looking for a .hg/dirstate in parent directory of module (or in module/.hg if
is_path is True), and parse dirstate file to get revision
@param module(unicode): module to look for (e.g. sat, libervia)
module can be a path if is_path is True (see below)
@param as_string(bool): if True return a string, else return a dictionary
@param is_path(bool): if True "module" is not handled as a module name, but as an
absolute path to the parent of a ".hg" directory
@param save_path(str, None): if not None, the value will be saved to given path as a pickled dict
/!\\ the .hg_data file in the given directory will be overwritten
@return (unicode, dictionary): retrieved info in a nice string,
or a dictionary with retrieved data (key is not present if data is not found),
key can be:
@ -69,7 +80,13 @@ def getRepositoryData(module, as_string=True):
from distutils.spawn import find_executable
import subprocess
KEYS=("node", "node_short", "branch", "date", "tag")
repos_root = os.path.dirname(module.__file__)
ori_cwd = os.getcwd()
if is_path:
repos_root = module
else:
repos_root = os.path.dirname(module.__file__)
hg_path = find_executable('hg')
if hg_path is not None:
@ -88,8 +105,27 @@ def getRepositoryData(module, as_string=True):
hg_data = {}
if not hg_data:
log.debug(u"Mercurial not available or working, trying to get data from dirstate")
os.chdir(os.path.relpath('..', repos_root))
# .hg_data pickle method
log.debug(u"Mercurial not available or working, trying other methods")
if save_dir_path is None:
log.debug(u"trying .hg_data method")
try:
with open(os.path.join(repos_root, '.hg_data')) as f:
import cPickle as pickle
hg_data = pickle.load(f)
except IOError as e:
log.debug(u"Can't access .hg_data file: {}".format(e))
except pickle.UnpicklingError:
log.warning(u"Error while reading {}, can't get repos data".format(f.name))
if not hg_data:
# .hg/dirstate method
log.debug(u"trying dirstate method")
if is_path:
os.chdir(repos_root)
else:
os.chdir(os.path.relpath('..', repos_root))
try:
with open('.hg/dirstate') as hg_dirstate:
hg_data['node'] = hg_dirstate.read(20).encode('hex')
@ -97,6 +133,25 @@ def getRepositoryData(module, as_string=True):
except IOError:
log.warning(u"Can't access repository data")
# we restore original working dir
os.chdir(ori_cwd)
# data saving
if save_dir_path is not None and hg_data:
if not os.path.isdir(save_dir_path):
log.warning(u"Given path is not a directory, can't save data")
else:
import cPickle as pickle
dest_path = os.path.join(save_dir_path, ".hg_data")
try:
with open(dest_path, 'w') as f:
pickle.dump(hg_data, f, 2)
except IOError as e:
log.warning(u"Can't save file to {path}: {reason}".format(
path=dest_path, reason=e))
else:
log.debug(u"repository data saved to {}".format(dest_path))
if as_string:
if not hg_data:
return u'repository data unknown'