mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
[FR] Switch from git to dulwich (#4966)
* [FR] Switch from pure git to dulwich Fixes #4942 * fix lenght * change length again * change length again
This commit is contained in:
parent
2ed7eefa27
commit
58a33c2e67
@ -3,17 +3,27 @@
|
|||||||
Provides information on the current InvenTree version
|
Provides information on the current InvenTree version
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import datetime
|
||||||
import os
|
import os
|
||||||
|
import pathlib
|
||||||
import re
|
import re
|
||||||
import subprocess
|
|
||||||
|
|
||||||
import django
|
import django
|
||||||
|
|
||||||
|
from dulwich.repo import NotGitRepository, Repo
|
||||||
|
|
||||||
from .api_version import INVENTREE_API_VERSION
|
from .api_version import INVENTREE_API_VERSION
|
||||||
|
|
||||||
# InvenTree software version
|
# InvenTree software version
|
||||||
INVENTREE_SW_VERSION = "0.12.0 dev"
|
INVENTREE_SW_VERSION = "0.12.0 dev"
|
||||||
|
|
||||||
|
# Discover git
|
||||||
|
try:
|
||||||
|
main_repo = Repo(pathlib.Path(__file__).parent.parent.parent)
|
||||||
|
main_commit = main_repo[main_repo.head()]
|
||||||
|
except NotGitRepository:
|
||||||
|
main_commit = None
|
||||||
|
|
||||||
|
|
||||||
def inventreeInstanceName():
|
def inventreeInstanceName():
|
||||||
"""Returns the InstanceName settings for the current database."""
|
"""Returns the InstanceName settings for the current database."""
|
||||||
@ -93,30 +103,6 @@ def inventreeDjangoVersion():
|
|||||||
return django.get_version()
|
return django.get_version()
|
||||||
|
|
||||||
|
|
||||||
git_available: bool = None # is git available and used by the install?
|
|
||||||
|
|
||||||
|
|
||||||
def check_for_git():
|
|
||||||
"""Check if git is available on the install."""
|
|
||||||
global git_available
|
|
||||||
|
|
||||||
if git_available is not None:
|
|
||||||
return git_available
|
|
||||||
|
|
||||||
try:
|
|
||||||
subprocess.check_output('git --version'.split(), stderr=subprocess.DEVNULL)
|
|
||||||
except Exception:
|
|
||||||
git_available = False
|
|
||||||
|
|
||||||
if git_available is None:
|
|
||||||
try:
|
|
||||||
subprocess.check_output('git status'.split(), stderr=subprocess.DEVNULL)
|
|
||||||
git_available = True
|
|
||||||
return True
|
|
||||||
except Exception:
|
|
||||||
git_available = False
|
|
||||||
|
|
||||||
|
|
||||||
def inventreeCommitHash():
|
def inventreeCommitHash():
|
||||||
"""Returns the git commit hash for the running codebase."""
|
"""Returns the git commit hash for the running codebase."""
|
||||||
# First look in the environment variables, i.e. if running in docker
|
# First look in the environment variables, i.e. if running in docker
|
||||||
@ -125,13 +111,9 @@ def inventreeCommitHash():
|
|||||||
if commit_hash:
|
if commit_hash:
|
||||||
return commit_hash
|
return commit_hash
|
||||||
|
|
||||||
if not check_for_git():
|
if main_commit is None:
|
||||||
return None
|
|
||||||
|
|
||||||
try:
|
|
||||||
return str(subprocess.check_output('git rev-parse --short HEAD'.split()), 'utf-8').strip()
|
|
||||||
except Exception: # pragma: no cover
|
|
||||||
return None
|
return None
|
||||||
|
return main_commit.sha().hexdigest()[0:7]
|
||||||
|
|
||||||
|
|
||||||
def inventreeCommitDate():
|
def inventreeCommitDate():
|
||||||
@ -142,11 +124,6 @@ def inventreeCommitDate():
|
|||||||
if commit_date:
|
if commit_date:
|
||||||
return commit_date.split(' ')[0]
|
return commit_date.split(' ')[0]
|
||||||
|
|
||||||
if not check_for_git():
|
if main_commit is None:
|
||||||
return None
|
|
||||||
|
|
||||||
try:
|
|
||||||
d = str(subprocess.check_output('git show -s --format=%ci'.split()), 'utf-8').strip()
|
|
||||||
return d.split(' ')[0]
|
|
||||||
except Exception: # pragma: no cover
|
|
||||||
return None
|
return None
|
||||||
|
return str(datetime.datetime.fromtimestamp(main_commit.commit_time).date())
|
||||||
|
@ -7,13 +7,11 @@ The main code for plugin special sauce is in the plugin registry in `InvenTree/p
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
from django.utils.translation import gettext_lazy as _
|
|
||||||
|
|
||||||
from maintenance_mode.core import set_maintenance_mode
|
from maintenance_mode.core import set_maintenance_mode
|
||||||
|
|
||||||
from InvenTree.ready import canAppAccessDatabase
|
from InvenTree.ready import canAppAccessDatabase
|
||||||
from plugin import registry
|
from plugin import registry
|
||||||
from plugin.helpers import check_git_version, log_error
|
|
||||||
|
|
||||||
logger = logging.getLogger('inventree')
|
logger = logging.getLogger('inventree')
|
||||||
|
|
||||||
@ -47,9 +45,3 @@ class PluginAppConfig(AppConfig):
|
|||||||
# drop out of maintenance
|
# drop out of maintenance
|
||||||
# makes sure we did not have an error in reloading and maintenance is still active
|
# makes sure we did not have an error in reloading and maintenance is still active
|
||||||
set_maintenance_mode(False)
|
set_maintenance_mode(False)
|
||||||
|
|
||||||
# check git version
|
|
||||||
registry.git_is_modern = check_git_version()
|
|
||||||
|
|
||||||
if not registry.git_is_modern: # pragma: no cover # simulating old git seems not worth it for coverage
|
|
||||||
log_error(_('Your environment has an outdated git version. This prevents InvenTree from loading plugin details.'), 'load')
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
"""Helpers for plugin app."""
|
"""Helpers for plugin app."""
|
||||||
|
|
||||||
|
import datetime
|
||||||
import inspect
|
import inspect
|
||||||
import logging
|
import logging
|
||||||
import pathlib
|
import pathlib
|
||||||
import pkgutil
|
import pkgutil
|
||||||
import subprocess
|
|
||||||
import sysconfig
|
import sysconfig
|
||||||
import traceback
|
import traceback
|
||||||
from importlib.metadata import entry_points
|
from importlib.metadata import entry_points
|
||||||
@ -14,6 +14,8 @@ from django.conf import settings
|
|||||||
from django.core.exceptions import AppRegistryNotReady
|
from django.core.exceptions import AppRegistryNotReady
|
||||||
from django.db.utils import IntegrityError
|
from django.db.utils import IntegrityError
|
||||||
|
|
||||||
|
from dulwich.repo import NotGitRepository, Repo
|
||||||
|
|
||||||
logger = logging.getLogger('inventree')
|
logger = logging.getLogger('inventree')
|
||||||
|
|
||||||
|
|
||||||
@ -109,21 +111,28 @@ def get_entrypoints():
|
|||||||
# region git-helpers
|
# region git-helpers
|
||||||
def get_git_log(path):
|
def get_git_log(path):
|
||||||
"""Get dict with info of the last commit to file named in path."""
|
"""Get dict with info of the last commit to file named in path."""
|
||||||
from plugin import registry
|
|
||||||
|
|
||||||
output = None
|
output = None
|
||||||
if registry.git_is_modern:
|
path = path.replace(str(settings.BASE_DIR.parent), '')[1:]
|
||||||
path = path.replace(str(settings.BASE_DIR.parent), '')[1:]
|
|
||||||
command = ['git', 'log', '-n', '1', "--pretty=format:'%H%n%aN%n%aE%n%aI%n%f%n%G?%n%GK'", '--follow', '--', path]
|
try:
|
||||||
|
walker = Repo.discover(path).get_walker(paths=[path.encode()], max_entries=1)
|
||||||
try:
|
try:
|
||||||
output = str(subprocess.check_output(command, cwd=settings.BASE_DIR.parent), 'utf-8')[1:-1]
|
commit = next(iter(walker)).commit
|
||||||
if output:
|
except StopIteration:
|
||||||
output = output.split('\n')
|
|
||||||
except subprocess.CalledProcessError: # pragma: no cover
|
|
||||||
pass
|
|
||||||
except FileNotFoundError: # pragma: no cover
|
|
||||||
# Most likely the system does not have 'git' installed
|
|
||||||
pass
|
pass
|
||||||
|
else:
|
||||||
|
output = [
|
||||||
|
commit.sha().hexdigest(),
|
||||||
|
commit.author.decode().split('<')[0][:-1],
|
||||||
|
commit.author.decode().split('<')[1][:-1],
|
||||||
|
datetime.datetime.fromtimestamp(commit.author_time, ).isoformat(),
|
||||||
|
commit.message.decode().split('\n')[0],
|
||||||
|
'E',
|
||||||
|
None
|
||||||
|
]
|
||||||
|
except NotGitRepository:
|
||||||
|
pass
|
||||||
|
|
||||||
if not output:
|
if not output:
|
||||||
output = 7 * [''] # pragma: no cover
|
output = 7 * [''] # pragma: no cover
|
||||||
@ -131,29 +140,6 @@ def get_git_log(path):
|
|||||||
return {'hash': output[0], 'author': output[1], 'mail': output[2], 'date': output[3], 'message': output[4], 'verified': output[5], 'key': output[6]}
|
return {'hash': output[0], 'author': output[1], 'mail': output[2], 'date': output[3], 'message': output[4], 'verified': output[5], 'key': output[6]}
|
||||||
|
|
||||||
|
|
||||||
def check_git_version():
|
|
||||||
"""Returns if the current git version supports modern features."""
|
|
||||||
# get version string
|
|
||||||
try:
|
|
||||||
output = str(subprocess.check_output(['git', '--version'], cwd=settings.BASE_DIR.parent), 'utf-8')
|
|
||||||
except subprocess.CalledProcessError: # pragma: no cover
|
|
||||||
return False
|
|
||||||
except FileNotFoundError: # pragma: no cover
|
|
||||||
# Most likely the system does not have 'git' installed
|
|
||||||
return False
|
|
||||||
|
|
||||||
# process version string
|
|
||||||
try:
|
|
||||||
version = output[12:-1].split(".")
|
|
||||||
if len(version) > 1 and version[0] == '2':
|
|
||||||
if len(version) > 2 and int(version[1]) >= 22:
|
|
||||||
return True
|
|
||||||
except ValueError: # pragma: no cover
|
|
||||||
pass
|
|
||||||
|
|
||||||
return False # pragma: no cover
|
|
||||||
|
|
||||||
|
|
||||||
class GitStatus:
|
class GitStatus:
|
||||||
"""Class for resolving git gpg singing state."""
|
"""Class for resolving git gpg singing state."""
|
||||||
|
|
||||||
|
@ -60,7 +60,6 @@ class PluginsRegistry:
|
|||||||
# flags
|
# flags
|
||||||
self.is_loading = False # Are plugins being loaded right now
|
self.is_loading = False # Are plugins being loaded right now
|
||||||
self.apps_loading = True # Marks if apps were reloaded yet
|
self.apps_loading = True # Marks if apps were reloaded yet
|
||||||
self.git_is_modern = True # Is a modern version of git available
|
|
||||||
|
|
||||||
self.installed_apps = [] # Holds all added plugin_paths
|
self.installed_apps = [] # Holds all added plugin_paths
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ django-user-sessions # user sessions in DB
|
|||||||
django-weasyprint # django weasyprint integration
|
django-weasyprint # django weasyprint integration
|
||||||
djangorestframework # DRF framework
|
djangorestframework # DRF framework
|
||||||
django-xforwardedfor-middleware # IP forwarding metadata
|
django-xforwardedfor-middleware # IP forwarding metadata
|
||||||
|
dulwich # pure Python git integration
|
||||||
drf-spectacular # DRF API documentation
|
drf-spectacular # DRF API documentation
|
||||||
feedparser # RSS newsfeed parser
|
feedparser # RSS newsfeed parser
|
||||||
gunicorn # Gunicorn web server
|
gunicorn # Gunicorn web server
|
||||||
|
@ -140,6 +140,8 @@ djangorestframework==3.14.0
|
|||||||
# drf-spectacular
|
# drf-spectacular
|
||||||
drf-spectacular==0.26.2
|
drf-spectacular==0.26.2
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
|
dulwich==0.21.5
|
||||||
|
# via -r requirements.in
|
||||||
et-xmlfile==1.1.0
|
et-xmlfile==1.1.0
|
||||||
# via openpyxl
|
# via openpyxl
|
||||||
feedparser==6.0.10
|
feedparser==6.0.10
|
||||||
@ -279,6 +281,7 @@ uritemplate==4.1.1
|
|||||||
# drf-spectacular
|
# drf-spectacular
|
||||||
urllib3==2.0.2
|
urllib3==2.0.2
|
||||||
# via
|
# via
|
||||||
|
# dulwich
|
||||||
# requests
|
# requests
|
||||||
# sentry-sdk
|
# sentry-sdk
|
||||||
wcwidth==0.2.6
|
wcwidth==0.2.6
|
||||||
|
Loading…
Reference in New Issue
Block a user