From 2900e815c4767044a7410f677c43bfefc014afad Mon Sep 17 00:00:00 2001 From: Goffi Date: Thu, 19 Mar 2015 19:47:01 +0100 Subject: [PATCH] =?UTF-8?q?core:=20if=20we=20are=20in=20dev=20version=20an?= =?UTF-8?q?d=20it's=20possible,=20repository=20data=20are=20now=20checked?= =?UTF-8?q?=20and=20added=20to=20S=C3=A0T=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bridge_constructor/bridge_template.ini | 2 +- src/core/sat_main.py | 23 ++++++- src/memory/memory.py | 2 +- src/tools/utils.py | 62 +++++++++++++++++++ 4 files changed, 84 insertions(+), 5 deletions(-) diff --git a/src/bridge/bridge_constructor/bridge_template.ini b/src/bridge/bridge_constructor/bridge_template.ini index bdbbe189..5bf053e5 100644 --- a/src/bridge/bridge_constructor/bridge_template.ini +++ b/src/bridge/bridge_constructor/bridge_template.ini @@ -160,7 +160,7 @@ type=method category=core sig_in= sig_out=s -doc=Get "Salut à Toi" version +doc=Get "Salut à Toi" full version [getProfileName] type=method diff --git a/src/core/sat_main.py b/src/core/sat_main.py index 07eb786d..520bb9c2 100644 --- a/src/core/sat_main.py +++ b/src/core/sat_main.py @@ -33,6 +33,7 @@ from sat.core.constants import Const as C from sat.memory.memory import Memory from sat.memory.crypto import PasswordHasher from sat.tools import trigger +from sat.tools import utils from sat.stdui import ui_contact_list, ui_profile_manager from glob import glob from uuid import uuid4 @@ -46,6 +47,7 @@ except ImportError: sat_id = 0 +__version__ = C.APP_VERSION def sat_next_id(): @@ -57,9 +59,24 @@ def sat_next_id(): class SAT(service.Service): @property - def __version__(self): + def version(self): + """Return the short version of SàT""" return C.APP_VERSION + @property + def full_version(self): + """Return the full version of SàT (with extra data when in development mode)""" + version = self.version + if version[-1] == 'D': + # we are in debug version, we add extra data + try: + return self._version_cache + except AttributeError: + self._version_cache = u"{} ({})".format(version, utils.getRepositoryData()) + return self._version_cache + else: + return version + def get_next_id(self): return sat_next_id() @@ -80,7 +97,7 @@ class SAT(service.Service): log.error(u"Bridge can't be initialised, can't start SàT core") sys.exit(1) self.bridge.register("getReady", lambda: self._initialised) - self.bridge.register("getVersion", lambda: C.APP_VERSION) + self.bridge.register("getVersion", lambda: self.full_version) self.bridge.register("getProfileName", self.memory.getProfileName) self.bridge.register("getProfilesList", self.memory.getProfilesList) self.bridge.register("getEntityData", lambda jid_, keys, profile: self.memory.getEntityData(jid.JID(jid_), keys, profile)) @@ -253,7 +270,7 @@ class SAT(service.Service): current.fallBack.setHandlerParent(current) current.versionHandler = xmpp.SatVersionHandler(C.APP_NAME_FULL, - C.APP_VERSION) + self.full_version) current.versionHandler.setHandlerParent(current) current.identityHandler = xmpp.SatIdentityHandler() diff --git a/src/memory/memory.py b/src/memory/memory.py index 87729fb8..99df9a9b 100644 --- a/src/memory/memory.py +++ b/src/memory/memory.py @@ -226,7 +226,7 @@ class Memory(object): fixLocalDir(False) # XXX: tmp update code, will be removed in the future self.config = self.parseMainConf() database_file = os.path.expanduser(os.path.join(self.getConfig('', 'local_dir'), C.SAVEFILE_DATABASE)) - self.storage = SqliteStorage(database_file, host.__version__) + self.storage = SqliteStorage(database_file, host.version) PersistentDict.storage = self.storage self.params = Params(host, self.storage) log.info(_("Loading default params template")) diff --git a/src/tools/utils.py b/src/tools/utils.py index e24391c7..4bf68ed5 100644 --- a/src/tools/utils.py +++ b/src/tools/utils.py @@ -20,10 +20,14 @@ """ various useful methods """ import unicodedata +import os.path +from sat.core.log import getLogger +log = getLogger(__name__) def clean_ustr(ustr): """Clean unicode string + remove special characters from unicode string""" def valid_chars(unicode_source): for char in unicode_source: @@ -32,3 +36,61 @@ def clean_ustr(ustr): yield char return ''.join(valid_chars(ustr)) +def getRepositoryData(as_string=True): + """Retrieve info on current mecurial repository + + @param as_string(bool): if True return a string, else return a dictionary + @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: + - node: full revision number (40 bits) + - branch: branch name + - date: ISO 8601 format date + - tag: latest tag used in hierarchie + """ + from distutils.spawn import find_executable + import subprocess + import sat + KEYS=("node", "branch", "date", "tag") + sat_root = os.path.dirname(sat.__file__) + hg_path = find_executable('hg') + + if hg_path is not None: + os.chdir(sat_root) + try: + hg_data_raw = subprocess.check_output(["hg","parents","--template","{node}\n{branch}\n{date|isodate}\n{latesttag}"]) + except subprocess.CalledProcessError: + hg_data = {} + else: + hg_data = dict(zip(KEYS, hg_data_raw.split('\n'))) + try: + hg_data['modified'] = '+' in subprocess.check_output(["hg","id","-i"]) + except subprocess.CalledProcessError: + pass + + if not hg_data: + log.debug(u"Mercurial not available or working, trying to get data from dirstate") + os.chdir(os.path.relpath('..', sat_root)) + try: + with open('.hg/dirstate') as hg_dirstate: + hg_data['node'] = hg_dirstate.read(20).encode('hex') + except IOError: + log.warning(u"Can't access repository data") + + if as_string: + if not hg_data: + return u'repository data unknown' + strings = [u'rev', hg_data['node']] + try: + if hg_data['modified']: + strings.append(u"[M]") + except KeyError: + pass + try: + strings.extend([u'({branch} {date})'.format(**hg_data)]) + except KeyError: + pass + + return u' '.join(strings) + else: + return hg_data