summaryrefslogtreecommitdiff
path: root/src/leap
diff options
context:
space:
mode:
authorkali <kali@leap.se>2012-09-13 04:59:08 +0900
committerkali <kali@leap.se>2012-09-13 04:59:08 +0900
commit157dbbd6dba18a0b10ba045eab9b1cfca8d579c6 (patch)
tree06fcac9f0c4d059899e0842c4226720ea3f5106b /src/leap
parent99058b9f6536a3717ab82a9d77b09d5489334eb5 (diff)
parentffa95a22b2073f75d51af32232e150bf36395f31 (diff)
Merge branch 'feature/client-versioning' into develop
Close #533. Using versioneer for fetching version from git info and tags in a setup friendly way. Added info to logs and small about dialog.
Diffstat (limited to 'src/leap')
-rw-r--r--src/leap/__init__.py25
-rw-r--r--src/leap/_version.py197
-rw-r--r--src/leap/app.py2
-rw-r--r--src/leap/baseapp/systray.py14
-rw-r--r--src/leap/baseapp/unitychecks.py2
5 files changed, 238 insertions, 2 deletions
diff --git a/src/leap/__init__.py b/src/leap/__init__.py
index a7ae10e3..75bddd6d 100644
--- a/src/leap/__init__.py
+++ b/src/leap/__init__.py
@@ -1,5 +1,30 @@
+"""
+LEAP Encryption Access Project
+website: U{https://leap.se/}
+"""
+
from leap import eip
from leap import baseapp
from leap import util
__all__ = [eip, baseapp, util]
+
+__version__ = "unknown"
+try:
+ from ._version import get_versions
+ __version__ = get_versions()['version']
+ del get_versions
+except ImportError:
+ #running on a tree that has not run
+ #the setup.py setver
+ pass
+
+__appname__ = "unknown"
+try:
+ from leap._appname import __appname__
+except ImportError:
+ #running on a tree that has not run
+ #the setup.py setver
+ pass
+
+__full_version__ = __appname__ + '/' + str(__version__)
diff --git a/src/leap/_version.py b/src/leap/_version.py
new file mode 100644
index 00000000..c33430ea
--- /dev/null
+++ b/src/leap/_version.py
@@ -0,0 +1,197 @@
+
+IN_LONG_VERSION_PY = True
+# This file helps to compute a version number in source trees obtained from
+# git-archive tarball (such as those provided by githubs download-from-tag
+# feature). Distribution tarballs (build by setup.py sdist) and build
+# directories (produced by setup.py build) will contain a much shorter file
+# that just contains the computed version number.
+
+# This file is released into the public domain. Generated by
+# versioneer-0.7+ (https://github.com/warner/python-versioneer)
+
+# these strings will be replaced by git during git-archive
+git_refnames = "$Format:%d$"
+git_full = "$Format:%H$"
+
+
+import subprocess
+import sys
+
+def run_command(args, cwd=None, verbose=False):
+ try:
+ # remember shell=False, so use git.cmd on windows, not just git
+ p = subprocess.Popen(args, stdout=subprocess.PIPE, cwd=cwd)
+ except EnvironmentError:
+ e = sys.exc_info()[1]
+ if verbose:
+ print("unable to run %s" % args[0])
+ print(e)
+ return None
+ stdout = p.communicate()[0].strip()
+ if sys.version >= '3':
+ stdout = stdout.decode()
+ if p.returncode != 0:
+ if verbose:
+ print("unable to run %s (error)" % args[0])
+ return None
+ return stdout
+
+
+import sys
+import re
+import os.path
+
+def get_expanded_variables(versionfile_source):
+ # the code embedded in _version.py can just fetch the value of these
+ # variables. When used from setup.py, we don't want to import
+ # _version.py, so we do it with a regexp instead. This function is not
+ # used from _version.py.
+ variables = {}
+ try:
+ for line in open(versionfile_source,"r").readlines():
+ if line.strip().startswith("git_refnames ="):
+ mo = re.search(r'=\s*"(.*)"', line)
+ if mo:
+ variables["refnames"] = mo.group(1)
+ if line.strip().startswith("git_full ="):
+ mo = re.search(r'=\s*"(.*)"', line)
+ if mo:
+ variables["full"] = mo.group(1)
+ except EnvironmentError:
+ pass
+ return variables
+
+def versions_from_expanded_variables(variables, tag_prefix, verbose=False):
+ refnames = variables["refnames"].strip()
+ if refnames.startswith("$Format"):
+ if verbose:
+ print("variables are unexpanded, not using")
+ return {} # unexpanded, so not in an unpacked git-archive tarball
+ refs = set([r.strip() for r in refnames.strip("()").split(",")])
+ for ref in list(refs):
+ if not re.search(r'\d', ref):
+ if verbose:
+ print("discarding '%s', no digits" % ref)
+ refs.discard(ref)
+ # Assume all version tags have a digit. git's %d expansion
+ # behaves like git log --decorate=short and strips out the
+ # refs/heads/ and refs/tags/ prefixes that would let us
+ # distinguish between branches and tags. By ignoring refnames
+ # without digits, we filter out many common branch names like
+ # "release" and "stabilization", as well as "HEAD" and "master".
+ if verbose:
+ print("remaining refs: %s" % ",".join(sorted(refs)))
+ for ref in sorted(refs):
+ # sorting will prefer e.g. "2.0" over "2.0rc1"
+ if ref.startswith(tag_prefix):
+ r = ref[len(tag_prefix):]
+ if verbose:
+ print("picking %s" % r)
+ return { "version": r,
+ "full": variables["full"].strip() }
+ # no suitable tags, so we use the full revision id
+ if verbose:
+ print("no suitable tags, using full revision id")
+ return { "version": variables["full"].strip(),
+ "full": variables["full"].strip() }
+
+def versions_from_vcs(tag_prefix, versionfile_source, verbose=False):
+ # this runs 'git' from the root of the source tree. That either means
+ # someone ran a setup.py command (and this code is in versioneer.py, so
+ # IN_LONG_VERSION_PY=False, thus the containing directory is the root of
+ # the source tree), or someone ran a project-specific entry point (and
+ # this code is in _version.py, so IN_LONG_VERSION_PY=True, thus the
+ # containing directory is somewhere deeper in the source tree). This only
+ # gets called if the git-archive 'subst' variables were *not* expanded,
+ # and _version.py hasn't already been rewritten with a short version
+ # string, meaning we're inside a checked out source tree.
+
+ try:
+ here = os.path.abspath(__file__)
+ except NameError:
+ # some py2exe/bbfreeze/non-CPython implementations don't do __file__
+ return {} # not always correct
+
+ # versionfile_source is the relative path from the top of the source tree
+ # (where the .git directory might live) to this file. Invert this to find
+ # the root from __file__.
+ root = here
+ if IN_LONG_VERSION_PY:
+ for i in range(len(versionfile_source.split("/"))):
+ root = os.path.dirname(root)
+ else:
+ root = os.path.dirname(here)
+ if not os.path.exists(os.path.join(root, ".git")):
+ if verbose:
+ print("no .git in %s" % root)
+ return {}
+
+ GIT = "git"
+ if sys.platform == "win32":
+ GIT = "git.cmd"
+ stdout = run_command([GIT, "describe", "--tags", "--dirty", "--always"],
+ cwd=root)
+ if stdout is None:
+ return {}
+ if not stdout.startswith(tag_prefix):
+ if verbose:
+ print("tag '%s' doesn't start with prefix '%s'" % (stdout, tag_prefix))
+ return {}
+ tag = stdout[len(tag_prefix):]
+ stdout = run_command([GIT, "rev-parse", "HEAD"], cwd=root)
+ if stdout is None:
+ return {}
+ full = stdout.strip()
+ if tag.endswith("-dirty"):
+ full += "-dirty"
+ return {"version": tag, "full": full}
+
+
+def versions_from_parentdir(parentdir_prefix, versionfile_source, verbose=False):
+ if IN_LONG_VERSION_PY:
+ # We're running from _version.py. If it's from a source tree
+ # (execute-in-place), we can work upwards to find the root of the
+ # tree, and then check the parent directory for a version string. If
+ # it's in an installed application, there's no hope.
+ try:
+ here = os.path.abspath(__file__)
+ except NameError:
+ # py2exe/bbfreeze/non-CPython don't have __file__
+ return {} # without __file__, we have no hope
+ # versionfile_source is the relative path from the top of the source
+ # tree to _version.py. Invert this to find the root from __file__.
+ root = here
+ for i in range(len(versionfile_source.split("/"))):
+ root = os.path.dirname(root)
+ else:
+ # we're running from versioneer.py, which means we're running from
+ # the setup.py in a source tree. sys.argv[0] is setup.py in the root.
+ here = os.path.abspath(sys.argv[0])
+ root = os.path.dirname(here)
+
+ # Source tarballs conventionally unpack into a directory that includes
+ # both the project name and a version string.
+ dirname = os.path.basename(root)
+ if not dirname.startswith(parentdir_prefix):
+ if verbose:
+ print("guessing rootdir is '%s', but '%s' doesn't start with prefix '%s'" %
+ (root, dirname, parentdir_prefix))
+ return None
+ return {"version": dirname[len(parentdir_prefix):], "full": ""}
+
+tag_prefix = ""
+parentdir_prefix = "leap_client-"
+versionfile_source = "src/leap/_version.py"
+
+def get_versions(default={"version": "unknown", "full": ""}, verbose=False):
+ variables = { "refnames": git_refnames, "full": git_full }
+ ver = versions_from_expanded_variables(variables, tag_prefix, verbose)
+ if not ver:
+ ver = versions_from_vcs(tag_prefix, versionfile_source, verbose)
+ if not ver:
+ ver = versions_from_parentdir(parentdir_prefix, versionfile_source,
+ verbose)
+ if not ver:
+ ver = default
+ return ver
+
diff --git a/src/leap/app.py b/src/leap/app.py
index 322118c5..b721468f 100644
--- a/src/leap/app.py
+++ b/src/leap/app.py
@@ -5,6 +5,7 @@ import sip
sip.setapi('QVariant', 2)
from PyQt4.QtGui import (QApplication, QSystemTrayIcon, QMessageBox)
+from leap import __version__ as VERSION
from leap.baseapp.mainwindow import LeapWindow
from leap.baseapp import unitychecks
@@ -45,6 +46,7 @@ def main():
logger.debug('args: %s' % opts)
logger.info('Starting app')
+ logger.info('Running client version %s', VERSION)
app = QApplication(sys.argv)
unitychecks.do_check()
diff --git a/src/leap/baseapp/systray.py b/src/leap/baseapp/systray.py
index c696ee74..762dac13 100644
--- a/src/leap/baseapp/systray.py
+++ b/src/leap/baseapp/systray.py
@@ -1,6 +1,7 @@
from PyQt4 import QtCore
from PyQt4 import QtGui
+from leap import __version__ as VERSION
from leap.gui import mainwindow_rc
@@ -82,6 +83,9 @@ class StatusAwareTrayIconMixin(object):
self.trayIconMenu.addAction(self.maximizeAction)
self.trayIconMenu.addAction(self.restoreAction)
self.trayIconMenu.addSeparator()
+ self.trayIconMenu.addAction(self.aboutAct)
+ self.trayIconMenu.addAction(self.aboutQtAct)
+ self.trayIconMenu.addSeparator()
self.trayIconMenu.addAction(self.quitAction)
self.trayIcon = QtGui.QSystemTrayIcon(self)
@@ -104,9 +108,19 @@ class StatusAwareTrayIconMixin(object):
triggered=self.showMaximized)
self.restoreAction = QtGui.QAction("&Restore", self,
triggered=self.showNormal)
+ self.aboutAct = QtGui.QAction("&About", self,
+ triggered=self.about)
+ self.aboutQtAct = QtGui.QAction("About Q&t", self,
+ triggered=QtGui.qApp.aboutQt)
self.quitAction = QtGui.QAction("&Quit", self,
triggered=self.cleanupAndQuit)
+ def about(self):
+ # move to widget
+ QtGui.QMessageBox.about(self, "About",
+ "Running LEAP client<br>"
+ "version <b>%s</b>" % VERSION)
+
def setConnWidget(self, icon_name):
oldlayout = self.statusIconBox.layout()
diff --git a/src/leap/baseapp/unitychecks.py b/src/leap/baseapp/unitychecks.py
index 72c9ee6f..2d06f629 100644
--- a/src/leap/baseapp/unitychecks.py
+++ b/src/leap/baseapp/unitychecks.py
@@ -10,9 +10,7 @@ import platform
import sys
from subprocess import Popen, PIPE
-logging.basicConfig()
logger = logging.getLogger(__name__)
-logger.setLevel('DEBUG')
from leap.base.constants import APP_NAME
from leap.baseapp.dialogs import ErrorDialog