Log the git revision if applicable

During development, the version number does not have much meaning... but
when faced with a reported issue, you would still like to know in more
detail what version of the Manuskript code was at work there.

Knowing the exact git revision will hopefully make it easier to
troubleshoot such issues in the future.

Note: this code takes special care to not rely on external modules
(we have enough dependencies) or even the git executable (invoking a
program can be relatively slow on some operating systems). It might not
handle all the edge cases, but I think it should cover our needs well
enough.
This commit is contained in:
Jan Wester 2019-10-15 14:32:07 +02:00
parent 239e66e7cb
commit c797b5a18b
2 changed files with 53 additions and 1 deletions

View file

@ -3,6 +3,8 @@
import os
import re
import sys
import pathlib
from random import *
from PyQt5.QtCore import Qt, QRect, QStandardPaths, QObject, QRegExp, QDir
@ -13,6 +15,9 @@ from PyQt5.QtWidgets import qApp, QFileDialog
from manuskript.enums import Outline
import logging
LOGGER = logging.getLogger(__name__)
# Used to detect multiple connections
AUC = Qt.AutoConnection | Qt.UniqueConnection
MW = None
@ -493,5 +498,47 @@ def getSearchResultContext(text, startPos, endPos):
return context
# Based on answer by jfs at:
# https://stackoverflow.com/questions/3718657/how-to-properly-determine-current-script-directory
def getManuskriptPath(follow_symlinks=True):
"""Used to obtain the path Manuskript is located at."""
if getattr(sys, 'frozen', False): # py2exe, PyInstaller, cx_Freeze
path = os.path.abspath(sys.executable)
else:
import inspect
path = inspect.getabsfile(getManuskriptPath) + "/../.."
if follow_symlinks:
path = os.path.realpath(path)
return os.path.dirname(path)
# Based on answer by kagronik at:
# https://stackoverflow.com/questions/14989858/get-the-current-git-hash-in-a-python-script
def getGitRevision(base_path):
"""Get git revision without relying on external processes or libraries."""
git_dir = pathlib.Path(base_path) / '.git'
if not git_dir.exists():
return None
with (git_dir / 'HEAD').open('r') as head:
ref = head.readline().split(' ')[-1].strip()
with (git_dir / ref).open('r') as git_hash:
return git_hash.readline().strip()
def getGitRevisionAsString(base_path, short=False):
"""Catches errors and presents a nice string."""
try:
rev = getGitRevision(base_path)
if rev is not None:
if short:
rev = rev[:7]
return "#" + rev
else:
return "" # not a git repository
except Exception as e:
LOGGER.warning("Failed to obtain Git revision: %s", e)
return "#ERROR"
# Spellchecker loads writablePath from this file, so we need to load it after they get defined
from manuskript.functions.spellchecker import Spellchecker

View file

@ -157,6 +157,8 @@ def attributesFromOptionalModule(module, *attributes):
# The list is consumed as a part of the unpacking syntax.
return v
import pathlib
def logVersionInformation(logger=None):
"""Logs all important runtime information neatly together.
@ -174,8 +176,11 @@ def logVersionInformation(logger=None):
logger.info("Hardware: %s / %s", machine(), processor())
# Manuskript and Python info.
from manuskript.functions import getGitRevisionAsString, getManuskriptPath
from manuskript.version import getVersion
logger.info("Manuskript %s (Python %s)", getVersion(), python_version())
logger.info("Manuskript %s%s (Python %s)", getVersion(),
getGitRevisionAsString(getManuskriptPath(), short=True),
python_version())
# Installed Python packages.